3
votes
#include <iostream>

using namespace std;

struct A {
    // Some Other Code
    int x;
};

A a1;

int main(){
    A a2;
    cout << "a1.x = " << a1.x << endl;
    cout << "a2.x = " << a2.x << endl;
    return 0;
}

C++14 Standard (ISO/IEC 14882:2014) Section 8.5, Paragraph 12:

If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.17). [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. - end note ]

So does a1 have Static Storage Duration and does a2 have Automatic Storage Duration? The definition of Struct A is at global namespace, as well as a1 declaration, while a2 declaration is at block scope (inside the main() function).

Also, Section 3.6.2 says:

Paragraph 1:

Non-local variables with static storage duration are initialized as a consequence of program initiation.

Paragraph 2:

Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place.

Besides, with gcc 5.4.0 I get a warning (warning: 'a2.A::x' is used uninitialized in this function [-Wuninitialized]) and a random value, but with clang 3.8.0 the output is always a2.x = 0 (zero can also be an indeterminate value). I also made other more complex experiments, with nested structs and default initializations placed in // Some Other Code. Sometimes I get random values and other times (not a negligible number of) I get a zero.

  • What is the Storage Duration of Struct A? And that of objects a1 and a2? And that of variables a1.x and a2.x?

  • Shoud a1.x and a2.x be zero-initialized? Or are they indeterminate values?

  • Do the same rules apply to class and union?

  • Does it make any difference the code in // Some Other Code? For example, if a class T "has non-static members with default initializers" (like in struct A { int b = 1; int x; };) then the default constructor can not be trivial (i.e. can not perform no action). Would that non-trivial constructor also initialize x? Trivial Default Constructor

Interesting links:

C++ Structure Initialization

Initializing default values in a struct

Are members of a C++ struct initialized to 0 by default?

Default initialization of POD types in C++

Initialization of Objects with Static Storage Duration in C vs C++

C and C++ : Partial initialization of automatic structure

How to initialize structures to all-elements-zero-or-null

2
a1 is default-initialized, a2 is not.Erik Alapää
I answered your questions except the last one, as I find it unclear. Could you rephrase it?Vittorio Romeo
@VittorioRomeo You are right, I'm sorry, that point was not clearly explained, I just edited it. My question was if a non-trivial constructor would also initialize (¿zero-initialize?) the remaining members of the struct that have not default initializers. Thanks.J L

2 Answers

5
votes

So does a1 have Static Storage Duration and does a2 have Automatic Storage Duration?

The definition of Struct A is at global namespace ...

This is irrelevant.

... is at global namespace, as well as a1 declaration

a1 has static storage duration and it is zero-initialized.

while a2 declaration is at block scope

a2 is a non-static block local variable. It has automatic storage duration and it is default initialized. It has an indeterminate value.


What is the Storage Duration of Struct A?

Types do not have storage duration. Objects do.

... And that of objects a1 and a2?

See above.

.. And that of variables a1.x and a2.x?

Subobjects, including non static data members, inherit the lifetime of their superobject.

... Shoud a1.x and a2.x be zero-initialized? Or are they indeterminate values?

a1 is zero initialized. This includes its subobjects. a2 is not. This includes its subobjects.

Do the same rules apply to class and union?

Same set of rules apply to objects of union and non-union classes as well as non class types when it comes to storage classes. There are differences in what default initialization means for different types.

Does it make any difference the code in // Some Other Code? For example, if a constructor of class T "has non-static members with default initializers" then the default constructor can not be trivial (i.e. perform no action).

A non-trivial default constructor generated by the compiler default initializes the members that have no default initializers.

2
votes

What is the Storage Duration of Struct A?

This question does not make sense, the storage depends on how A is used.


And that of objects a1 and a2?

a1 has static storage. See this question for more details.

a2 has automatic storage.


And that of variables a1.x and a2.x?

They are stored the same way as their parent A instance.


Do the same rules apply to class and union?

Yes.