是否复制了POD类型的填充字节?

时间:2017-10-22 14:10:27

标签: c++ copy-constructor

假设我有这样的POD类型:

struct A {
    char a;
    int b;
};

在我的系统sizeof(A) == 8上,即使是sizeof(char) == 1sizeof(b) == 4。这意味着数据结构有3个未使用的字节。

现在假设我们

A x = ...;
A y =x;

问题:

是否保证xy的所有8个字节都相同,即使是那些未使用过的3个字节?

等效地,如果我将一些A对象的基础字节转移到另一个不理解其含义或结构的程序,并将它们视为一个8字节的数组,那么其他程序可以安全地比较两个A 1}} s for equality?

注意:In an experiment with gcc 7,似乎会复制这些字节。我想知道这是否有保障。

4 个答案:

答案 0 :(得分:42)

  

非联合类X的隐式定义的复制/移动构造函数执行成员复制/移动   其基地和成员。

12.8 / 15 [class.copy]在N4141中

因此允许填充字节中的位模式不同。

答案 1 :(得分:7)

它不具有权威性,但std::memcmpcppreference条目表明填充字节可能不同:

  两个memcmp()类型的对象之间的

struct{char c; int n;}将比较cn的值相同时,其值可能不同的填充字节

答案 2 :(得分:6)

鉴于您询问了 POD类型(因此包括工会),值得一提的是,根据[class.copy]

  

联合X的隐式定义的复制/移动构造函数复制X的对象表示(6.9)

对于简单的可复制类型,也应包括填充位。 所以,这可能只是用

替换A的问题
union A{ struct {
    char a;
    int b;
}; };

(实际上,上面使用的是非标准的匿名结构,但你明白了......)

答案 3 :(得分:4)

回答你的第二个问题:

  

等效地,如果我将一些A对象的底层字节转移到另一个不理解其含义或结构的程序,并将它们视为一个8字节的数组,那么其他程序可以安全地比较两个As是否相等?

由于您的类型的对象可能包含填充字节,因此另一个程序通常无法比较两个此类对象的相等性:

知道在语义上构成对象的字节的是定义其值表​​示的关键。然而,在这种情况下,目标程序仅知道对象表示,即表示存储器中的这种对象的字节的序列,包括填充字节。像memcmp这样的函数只能以有意义的方式比较其值表示与其对象表示相同的对象。如果你使用它来逐个比较对象,即使它们有填充,也可能无法给出正确的结果,因为它无法分辨对象表示中的哪些位与两个对象的值表示相等无关。

请参阅http://en.cppreference.com/w/cpp/language/object