変数のアライメント

構造体または変数のアライメントを設定する構文として
GCCに__attribute__*1
がある。どちらも2の累乗の値を指定する。

  • 構造体のメンバーのアライン
  • 変数の配置の指定

が可能となっている。


GCCの場合、変数の配置の指定はアセンブラの.align擬似命令(リンカの配置指令)で実現されている。なので、静的配置には有効だが、スタック上の変数に対しては有効でない。
SIZEとして指定できる値は、プラットフォーム毎のリンカの仕様に規定される。
x86の場合は16まで。例えばMMX/SSEでは16バイトアラインが必要なケースがある。32以上が必要になるシチュエーションは、たぶんない。


一方、VC++の方は型宣言に対してだけでなく、スタック上の変数にも有効で、

__declspec(align(128)) char buffer[256];
とかやると、
char _buffer[256 + 127];
char *buffer = (char *)((size_t)(_buffer + 127) & -128);
としたのと同等の効果が得られる。
生成されたアセンブリリスティングを見てみたら
and  esp, -128
add esp, 4
push ebp
mov ebp, esp
という感じになっている(ebpが、アライン済のスタックの基底アドレスになる)。
add esp, 4ってアラインぶち壊しじゃないかと思ったら、push ebpで4バイト減るのの調整だった。
で、これVC++6.0じゃ使えないんだよね...

*1:aligned(SIZE))) VC++に__declspec(align(SIZE