如果我有这样的一个结构体:
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++ 吗?
至少在C语言中是这样的。编译器可以在任何结构成员后插入填充,但不能重新排列成员。
它也不能在第一个成员之前插入填充。
从C99开始,6.7.2.1
:
13/ 在结构对象内,非位域成员和位于位域中的单元按其声明顺序递增地具有地址。指向结构对象的指针进行适当转换后,指向其初始成员(或如果该成员是位域,则指向其中所在的单元),反之亦然。结构对象内可能存在未命名的填充,但不会出现在其开头。
15/ 结构体或联合体末尾可能有未命名的填充。
[[no_unique_address]]
注释a
、b
和c
,并且它们恰好是空结构,则可能会使它们都具有相同的地址。是的,默认情况下,C++编译器不允许移动结构体中的元素,这使得两个语句都变得微不足道。
是的(只要sizeof(任何类型)不为0。一些编译器允许它,这是非标准的--请参见sizeof能返回0吗)。您可以使用<=或假设使用标准编译器。
是的
在C++中也是如此。
指针比较只有在数组和结构/类内部才有意义,而不是通常情况下。