PODtypes的填充字节是否被复制?
假设我有这样的PODtypes:
struct A { char a; int b; };
在我的系统上, sizeof(A) == 8
,即使sizeof(char) == 1
和sizeof(b) == 4
。 这意味着数据结构有3个未使用的字节。
现在假设我们这样做
A x = ...; A y =x;
题:
是否保证x
和y
所有8个字节都是相同的,甚至3个未使用的字节?
等价地,如果我将一些A
对象的底层字节传输给另一个不明白其含义或结构的程序,并将它们视为一个8字节的数组,那么其他程序可以安全地比较两个A
的相等性吗?
注意: 在一个使用gcc 7的实验中 ,似乎这些字节被复制。 我想知道这是否有保证。
非工会类X的隐式定义的复制/移动构造函数执行其基础和成员的成员复制/移动。
N4141中的12.8 / 15 [class.copy]
因此填充字节中的位模式允许不同。
这不是权威性的,但cppreference
的std::memcmp
条目表明填充字节可能不同:
memcmp()
两个types为struct{char c; int n;}
struct{char c; int n;}
将比较c
和n
的值相同时,其值可能不同的填充字节
考虑到你问了PODtypes (因此包括工会)值得一提的是,根据[class.copy]
联合X的隐式定义的复制/移动构造函数复制X的对象表示 (6.9)
对于普通可复制types,也应该包含填充位。 所以,这可能只是一个取代A的问题
union A{ struct { char a; int b; }; };
(实际上,上面使用了一个非标准的匿名结构,但你明白了…)
回答你的第二个问题:
等价地,如果我将一些A对象的底层字节传输给另一个不明白其含义或结构的程序,并将它们视为一个8字节的数组,那么其他程序是否可以安全地比较两个As的相等性?
由于你的types的对象可能包含填充字节,另一个程序通常不能比较两个这样的对象是否相等:
知道在语义上形成对象的哪些字节是定义其值表示的关键。 但是,在这种情况下,目标程序只知道对象表示 ,即在内存中表示这种对象的字节序列,包括填充字节。 像memcmp这样的函数只能以有意义的方式比较其值对象表示与其对象表示相同的对象。 如果使用它来比较对象,即使它们具有填充值,也可能无法给出正确的结果,因为它无法分辨对象表示中的哪些位与两个对象的值表示是相等的。