为了能够执行一些系统的代码转换,我想在我的代码中删除#pragma pack
指令,并用本地属性替换它们,例如packed, aligned(n)
。
但是,我得到的行为并不完全相同:sizeof
有效,offsetof
会产生不同的结果。这是一个例子:
#include <stddef.h>
#include <stdio.h>
#include <stddef.h>
struct WITH_ATTRS {
char c;
double d;
} __attribute__((packed,aligned(4)));
#pragma pack(4)
struct PACK4 {
char c;
double d;
};
int main() {
printf("sizeof(WITH_ATTRS) = %zu\n", sizeof(struct WITH_ATTRS));
printf("offsetof(WITH_ATTRS, d) = %zu\n", offsetof(struct WITH_ATTRS, d));
printf("sizeof(PACK4) = %zu\n", sizeof(struct PACK4));
printf("offsetof(PACK4, d) = %zu\n", offsetof(struct PACK4, d));
return 0;
}
GCC(5.4.0)和Clang(3.8.0)都为我输出了同样的东西:
sizeof(WITH_ATTRS) = 12
offsetof(WITH_ATTRS, d) = 1
sizeof(PACK4) = 12
offsetof(PACK4, d) = 4
所以,我从中理解的是:
__attribute__((packed,aligned(4)))
在字段c
和d
之间没有间隔,但在结构的末尾,确保它是4的倍数(因此sizeof == 12
); #pragma pack(4)
在c
和d
之间留下3个字节的间隔,同时产生sizeof == 12
。是否有通用的方法来获取PACK4
的布局,但不使用编译指示?