【发布时间】:2013-01-14 17:09:35
【问题描述】:
我在一个项目中继承了一些第三方代码。它由一个头文件和一个没有源的二进制库组成,所以我不能用不同的设置重新编译它。
标头使用编译时类似断言的技巧(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)上编译:打包 pragma 根本没有任何效果。编译器不断将成员 a 对齐到 4 个字节(您可以通过注释掉 typedef 来检查)。
这是为什么呢?我怎样才能修复代码,以使这个断言不会失败并保持它与 ABI 兼容,同时又不必遍历标头中的所有结构并将 attributes 附加到它们的尾部?
【问题讨论】: