Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are extra bytes initialized to 0 in C++?

Suppose I have a struct that contains an int and a char:

struct thing_t {
    int value = 0;
    char other_value = 0;
};

Because of the way things are aligned in the memory, sizeof(thing_t) should be 8, since the size of the largest member is 4 bytes. If I create a default-initialized instance of thing_t, will the extra 3 bytes be initialized to 0?

I recognize that this normally wouldn't come up, but I was writing a hash function and the default behavior of the hash function is to hash a generic type as though it were an array of bytes. If the extra bytes were occasionally not initialized to 0, I realized that my approach could cause problems.

like image 248
Antonio Perez Avatar asked May 07 '18 20:05

Antonio Perez


2 Answers

I could not find anything in the C++11 standard about what happens to padding when an object is default initialized.

However, the standard is firm about padding when it comes zero-initialization.

From 8.5 Initializers/5

5.2 — if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;

5.3 — if T is a (possibly cv-qualified) union type, the object's first non-static named data member is zero-initialized and padding is initialized to zero bits;

I would advise using zero initialization instead of default initialization to force the padding bits to be initialized to zero. That would result in predictable values from your hash function.

like image 97
R Sahu Avatar answered Oct 11 '22 04:10

R Sahu


If I create a default-initialized instance of thing_t, will the extra 3 bytes be initialized to 0?

They may or may not be. There is no requirement for them to be zeroed.

Unfortunately you can't value-initialize the object to get it zero-initialized, which does zero the padding bits, because the default member initalizers stop it from being trivially constructable.

[dcl.init]/8

To value-initialize an object of type T means:

[...]

  • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;

[class.ctor]/6

A default constructor is trivial if it is not user-provided and if:

[...]

  • no non-static data member of its class has a default member initializer (12.2)
like image 39
NathanOliver Avatar answered Oct 11 '22 03:10

NathanOliver