Member Initializer Order

The following code gives the correct output if I declare the variables i and j , Like int i, j;

 class A { int i, j; public: A(int val) : i(val), j(i + 1) { cout<<i<<endl<<j<<endl; } }; 

But if I declare a variable i and j , for example int j, i; . then j print the garbage value .

 class A { int j, i; public: A(int val) : i(val), j(i + 1) { cout<<i<<endl<<j<<endl; } }; 

So, does it depend on the order of declaration of the variables?

+5
source share
3 answers

Does it depend on the order of declaration of variables?

Yes, data members are always initialized in the order of their declarations, which has nothing to do with the order of member initializer lists.

This means that for the second piece of code, j always initialized to i ; but when it is initialized with the initializer of member i , it is still not initialized.

Complete initialization order for an object:

(my emphasis)

The order of the member initializers in the list does not matter: the actual initialization order is as follows:

1) If the constructor is intended for the derived class itself, the virtual base classes are initialized in the order in which they appear at the intersection of depth left-right declarations of the base class (from left to right refers to the appearance of the base qualifier in the lists)

2) Then direct base classes are initialized in order from left to right, as they appear in this list of base class specifiers

3) Then the non-static data elements are initialized in the declaration order in the class definition .

4) Finally, the constructor body is executed

+2
source

Does it depend on the order of declaration of variables?

Absolutely! The order in which initializers appear in the initialization list is ignored by the standard; only the declaration procedure matters. This is done so that the "reverse initialization order" makes sense in the destructor, although there can potentially be several constructors with lists of initializers ordered in a different order.

Here is the relevant part of the C ++ standard (12.6.2.10):

In the constructor without delegation, initialization is performed in the following order:

  • First, and only for the constructor of the derived class (1.8) itself, the virtual base classes are initialized in the order in which they appear at the first left-right intersection of the directed acyclic graph of base classes, where "left-to-right" is the order of appearance base classes in the base-specifier-list of a derived class.
  • Then direct base classes are initialized in the order of declaration, as they appear in the list of base-qualifiers (regardless of the order of mem initializers).
  • Then, non-static data elements are initialized in the order in which they were declared in the class definition (again, regardless of the order of the mem initializers).
  • Finally, the compound instruction of the constructor body is executed.

[Note. The declaration order is set to ensure that the base and element subobjects are destroyed in the reverse order of initialization. - final note]

+2
source

Does it depend on the order of declaration of variables?

Yes, the order in which data items (i.e.: i and j in your class A ) is initialized corresponds to the order in which they are declared, and not to the order as they appear in the constructor list of member initializers.

Constructor member initializer list in class A

 A(int val) : i(val), j(i + 1) 

says nothing about the order in which these data items are initialized.

The data item j will still be initialized to i if j declared before i (i.e.: int j, i ). In this case, j initialized to i + 1 , but i not initialized at this point, which can lead to j containing garbage.


In GCC, you can get a warning displayed in these cases by providing the -Wreorder parameter, which is already enabled by passing the -Wall parameter.

+1
source

Source: https://habr.com/ru/post/1271143/


All Articles