アラインメントを緩和し、パッキングして変数を配置する
テクニカル・ノート 181214J
アーキテクチャ:
All
コンポーネント:
general
更新日:
2019/01/15 8:18
はじめに
このテクニカルノートでは、アラインメントを緩和し、パッキングして変数を配置する方法について説明します。
解説
構造体、共用体以外の変数の場合、次のようなメモリの宣言をすると、
int a;
char b;
int c;
char d;
…
大量のメモリの隙間ができてしまいそうに見えますが、コンパイル/リンク時点で、アラインメントの同じデータ型ごとにまとめられて配置されますので、実際に生ずる隙間は、アラインメントの異なるデータの集まりの継ぎ目の部分のみになりますので、変数を詰め込むための対策は特に必要ありません。
構造体、共用体の場合は、ソースファイル上のメンバの順に配置されますから隙間が発生します。この隙間を埋めてメンバを配置したい場合は、
__packed struct abc {...}
または、
#pragma pack()
を使用することができます。
ただし、正しくアラインメントされていないオブジェクトにアクセスする場合には、コードのサイズが大きくなり速度が低下します。そのような構造体・共用体へのアクセスが多数ある場合、packを行わず、同じデータ型ごとにまとめて配置するなどしてください。
また、アラインメントが正しく設定されていないメンバへのポインタ作成及び使用には、特別な注意も必要です。パックされたアラインメントが正しくない構造体メンバに直接アクセスする場合は、コンパイラは必要に応じて正しいコード(ただし、サイズが大きく低速)を出力しますが、ポインタを使用してそのメンバにアクセスする場合には、通常のコード(サイズが小さく高速)が使用されます。
まとめ
構造体およびそのメンバのアラインメント要件を下げるには、#pragma packまたは__packedデータ型属性__packedを使用できます。
全ての製品名は、それぞれの所有者の商標または登録商標です