読者です 読者をやめる 読者になる 読者になる

Alignment

structやclassにアラインメントを適用したい場合に色々ハマった。というかハマっている。


gccの場合、structやclassにアラインメントを適用したい場合は以下のようになる。

struct __attribute__((aligned(16))) THoge
{
  char FHoge[8];
};

struct TFoo
{
  char FFoo[12];
} __attribute__((aligned(16)));

int
main(void)
{
  std::cout << "THoge Size: " << sizeof(THoge) << std::endl;
  std::cout << "TFoo Size: " << sizeof(TFoo) << std::endl;

  return 0;
}

これを実行すると、

THogeSize: 16
TFoo Size: 16

というように、structやclassはアラインメントされた状態のサイズとなる。


さて、Visual C++で上記のようにアラインメントを適用したい場合は以下のようになる。

struct __declspec(align(16)) TBar
{
  char FBar[8];
};

int
main(void)
{
  std::cout << "TBar Size: " << sizeof(TBar) << std::endl;

  return 0;
}

これの実行結果は、

TBar Size: 16

たかだかアラインメントを設定するだけなのに、プラットフォーム以前にコンパイラによって書き方が異なるこの如何ともしがたい状況。
ただし、これならばまだ解決策はあって、

#if defined(MSC_VAR)
#define ATTRIBUTE_ALIGN(n) __declspec(align(n))
#else
#define ATTRIBUTE_ALIGN(n) __attribute__((aligned(n)))
#endif

struct ATTRIBUTE_ALIGN(16) TPiyo
{
  char FPiyo[12];
};

int
main(void)
{
  std::cout << "TPiyo Size: " << sizeof(TPiyo) << std::endl;

  return 0;
}

としておけば、どちらのコンパイラでも問題なくアライメントが適用される。


しかし、Visual C++側でアライメントを適用したstructやclassをvectorのテンプレートパラメータにしようとすると、[C2719]という、エラーメッセージが"_declspec(align(16)) の仮引数は配置されません。"のコンパイルエラーが生じる。
どうやら、"__declspec(align(#))"を使用した物はテンプレートパラメータにできないらしい。


な ん だ こ の 腐 っ た 仕 様 は ! ! ! !


解決策が見つからない。どうにもならないのか、これは……。