Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must initializer list order match member declaration order?

Tags:

Why does gcc throw a hissy fit if the initializer list order doesn't match variable order in the class?

class myClass { public:    int A;    int B;    myClass(); };  myClass::myClass() : B(1), A(2) {} 

will result in:

file.h:274: warning: 'myClass::A' will be initialized after file.h:273: warning:   'int myClass::B file.cpp:581: warning:   when initialized here 

Is there any specific reason why this kind of warning is issued? Are there any risks associated with initializing variables of a class in order different than they are defined within the class?

(note, there is a question which touches the subject, but the answers are pretty much "because it should be so" without giving any rationale as to why it should be ordered, or what's wrong with this being out of order - I'd like to know why such a restriction exists - could someone give an example where it may backfire maybe?)

like image 916
SF. Avatar asked Jun 18 '14 12:06

SF.


People also ask

When must you use a member initializer list?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

What is the advantage of using member initializer list?

The most common benefit of doing this is improved performance. If the expression whatever is the same type as member variable x_, the result of the whatever expression is constructed directly inside x_ — the compiler does not make a separate copy of the object.

In what order are class members attributes initialized?

The order in which members are initialized, including base class initialization, is determined by the declaration order of the class member variables or the base class specifier list. Writing member initializers other than in canonical order can result in undefined behavior, such as reading uninitialized memory.

Does initializer list run before constructor?

The initializer list is used to directly initialize data members of a class. An initializer list starts after the constructor name and its parameters.


1 Answers

The warning is indicating that regardless of the order you use in the constructor initialization list the standard requires that non-static data members be initialized in the order they were declared. We can see this by going to the draft C++ standard section 12.6.2 Initializing bases and members paragraph 10 which says:

In a non-delegating constructor, initialization proceeds in the following order:

and includes:

Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

Why does the standard require this? We can find a rationale for this in paper The Evolution of C++: 1985 to 1989 by Bjarne Stroustrup in section 6 it says:

The initialization takes place in the order of declaration in the class with base classes initialized before members,

[...]

The reason for ignoring the order of initializers is to preserve the usual FIFO ordering of constructor and destructor calls. Allowing two constructors to use different orders of initialization of bases and members would constrain implementations to use more dynamic and more expensive strategies

like image 120
Shafik Yaghmour Avatar answered Sep 29 '22 21:09

Shafik Yaghmour