struct成员内存布局

如果我有这样的结构:

struct S { ANY_TYPE a; ANY_TYPE b; ANY_TYPE c; } s; 

我可以安全地假设以下假设在所有平台上始终都是正确的吗?

 ((char *)&s.a) < ((char *)&s.c) ((char *)&s.a + sizeof(sa) + sizeof(sb)) <= ((char *)&s.c) 

在C ++中呢?

是的,至少在C中。 编译器可以在任何结构成员之后自由插入填充,但它不能对成员重新排序。

它也必须在第一个成员之前插入填充。

6.7.2.1

13 /在结构对象中,非位字段成员和位字段所在的单元具有按声明顺序增加的地址。 指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。 结构对象中可能存在未命名的填充,但不是在其开头。

15 /结构或联合的末尾可能有未命名的填充。

对于结构体而言,这是正确的,但只要引入访问说明符,就会对C ++进行更改。 允许编译器重新排序由访问说明符分隔的整个块。

在C ++中,您可以确定这些假设将成立。 在像这样的结构中,不允许编译器更改成员的顺序。

是的,默认情况下,C ++编译器不允许在结构中移动元素,这使得两个语句都是真的。

  1. 是(只要sizeof(ANY_TYPE)不为0.有些编译器允许它,这是非标准的 – 请参阅Can sizeof return 0(zero) )。 使用<=或者假设标准编译器是安全的。

而且在C ++中也是如此。

指针比较仅在数组和结构/类中有意义,而不是一般。