プロジェクトでいくつかのサードパーティ コードを継承しました。ヘッダー ファイルとソースのないバイナリ ライブラリで構成されているため、別の設定で再コンパイルすることはできません。
ヘッダーは、コンパイル時のアサートのようなトリック (typedef
式が失敗した場合は負のサイズの配列を使用する) を使用して、適切な構造体の配置を保証しますが、32 ビット モードでは機能しないようです。
問題全体をキャプチャするスタンドアロンの小さなプログラムを次に示します。
#include <stdio.h>
#include <stddef.h>
#pragma pack(push, 8)
struct test {char _; long long a;};
typedef char pack_test[(offsetof(test, a) == 8) ? 1 : -1];
#pragma pack(pop)
int main(int argc, char *argv[])
{
printf("%d\n", offsetof(test, a));
return 0;
}
上記のコードは、clang 3.0 と、すぐに手に入れることができる最近の gcc バージョン (4.5 から 4.7) の両方でコンパイルに失敗します。パッキング プラグマはまったく効果がありません。コンパイラはメンバーa
を 4 バイトに揃え続けます (コメントアウトすることで確認できますtypedef
)。
何故ですか?このアサーションが失敗しないようにコードを修正し、ABI との互換性を維持しながら、ヘッダー内のすべての構造体を調べて末尾にattribute
s を追加する必要がないようにするにはどうすればよいですか?