我们可以预测编译器如何实现C结构吗?
如果我写(非常严重的对齐)结构:
struct {
uint16_t a;
uint32_t b;
uint8_t c;
} s;
char *p = (char*)&s;
我可以保证p[6]
与s.c
相同吗?结构字段是以最明显和规范的方式分配的,因此我们可以预测每个字段在内存中的位置吗?
编辑:struct __attribute__ ((__packed__)) {...} s;
会让我在GCC中遇到这种行为吗?
答案 0 :(得分:7)
字段必须按升序分配,但编译器可以根据需要在字段之间插入填充,因此无法保证n
中p[n]
的值将引用s.c
。 OTOH,你可以使用offsetof(s,c)
获得正确的偏移量。
答案 1 :(得分:7)
不,你不能。不要那样做。
只保证订单,同一编译器将始终执行相同的布局。
如果你需要这样的话,请查阅你的编译器文档,了解如何启用字节打包(始终可用)并自己填充。
答案 2 :(得分:2)
即使使用__packed__
属性,由于架构限制,也可能无法实现此对齐。例如,如果uint32_t
需要4字节对齐,即使使用__packed__
,它也会偏移4。
如果您需要假设一个特定的对齐方式,请进行静态检查,以防止使用不同的对齐方式编译代码。
答案 3 :(得分:1)
对于给定版本的操作系统上的给定版本的编译器 - 并且具有相同的构建选项=是
但不要!
答案 4 :(得分:0)
请参阅#pragma pack(packed)
和#pragma pack(reset)
。它与您提到的GCC属性__packed__
具有相同的影响。