Do the padding bytes of a POD type get copied?

Suppose I have a POD type like this:

struct A {
    char a;
    int b;
};

On my system, sizeof(A) == 8, even though sizeof(char) == 1 and sizeof(b) == 4. This means that the data structure has 3 unused bytes.

Now suppose we do

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

Question:

Is it guaranteed that all 8 bytes of x and y will be identical, even those 3 unused ones?

Equivalently, if I transfer the underlying bytes of some A objects to another program that does not understand their meaning or structure, and treats them as an array of 8 bytes, can that other program safely compare two As for equality?

Note: In an experiment with gcc 7, it appears that those bytes do get copied. I would like to know if this is guaranteed.


Solution 1:

The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members.

12.8/15 [class.copy] in N4141

The bit pattern in the padding bytes is thus allowed to differ.

Solution 2:

It's not authoritative, but cppreference's entry for std::memcmp suggests that the padding bytes may differ:

memcmp() between two objects of type struct{char c; int n;} will compare the padding bytes whose values may differ when the values of c and n are the same

Solution 3:

given that you asked about a POD type ( hence including unions ) it's worth mentioning that according to [class.copy]

The implicitly-defined copy/move constructor for a union X copies the object representation (6.9) of X

that for trivially copyable types should include padding bits as well. So, it could be just a matter of replacing A with

union A{ struct {
    char a;
    int b;
}; };

(actually, the above uses a non standard anonymous struct, but you get the point ... )

Solution 4:

Answering your second question:

Equivalently, if I transfer the underlying bytes of some A objects to another program that does not understand their meaning or structure, and treats them as an array of 8 bytes, can that other program safely compare two As for equality?

As an object of your type may contain padding bytes, another program generally can not compare two such objects for equality:

Knowing which bits of the bytes that make out the object semantically is the key for defining its value representation. However, in this scenario, the target program only knows the object representation, i.e. the sequence of bytes representing such an object in memory, including padding bytes. A function like memcmp can only compare such objects whose value representation is identical to its object representation in a meaningful way. If you use it to compare objects value-wise even though they have padding, it may fail to give the right results as it cannot tell which bits in the object representation are irrelevant for the value representations of two objects to be equal.

See http://en.cppreference.com/w/cpp/language/object