如果我有这样的结构:
struct S {
ANY_TYPE a;
ANY_TYPE b;
ANY_TYPE c;
} s;
我可以安全地假设以下假设在所有平台上始终都是正确的吗?
((char *)&s.a) < ((char *)&s.c)
((char *)&s.a + sizeof(s.a) + sizeof(s.b)) <= ((char *)&s.c)
在C ++中呢?
答案 0 :(得分:5)
对于结构体来说,这是正确的,但只要引入访问说明符,就会对C ++进行更改。允许编译器重新排序由访问说明符分隔的整个块。
答案 1 :(得分:4)
是的,至少在C中。编译器可以在任何结构成员之后自由插入填充,但不能对成员重新排序。
它也必须在第一个成员之前插入填充。
来自C99,6.7.2.1
:
13 / 在结构对象中,非位字段成员和位字所在的单位具有按声明顺序增加的地址。指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。在结构对象中可能有未命名的填充,但不是在它的开头。
15 / 结构或联合的末尾可能有未命名的填充。
答案 2 :(得分:2)
这在C ++ 20中有所变化(至少是当前草案):如果用a
注释b
,c
和[[no_unique_address]]
,而它们恰好是空结构,它们都可能具有相同的地址。
实际上,它更复杂-如果任何两个为空并带有注释,则所有3个都可以共享一个地址。
答案 3 :(得分:1)
在C ++中,您可以确定这些假设将成立。在像这样的结构中,不允许编译器改变成员的顺序。
答案 4 :(得分:0)
是的,默认情况下,C ++编译器不允许在结构中移动元素,这使得两个语句都很简单。
答案 5 :(得分:0)
是(只要sizeof(ANY_TYPE)不为0.有些编译器允许它,这是非标准的 - 请参阅Can sizeof return 0 (zero))。使用&lt; =或者假设标准编译器是安全的。
是
在C ++中也是如此。
指针比较仅在数组和结构/类中有意义,而不是一般。