Constructor initialization-list evaluation order
It depends on the order of member variable declaration in the class. So a_
will be the first one, then b_
will be the second one in your example.
Evaluation order of elements in an initializer list
It seems to me that the quote is relevant (the compiler sees an initializer list):
8.5/14,16:
The initialization that occurs in the form
T x = a;
as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization.
.
.
The semantics of initializers are as follows[...]: If the initializer is a braced-init-list, the object is list-initialized (8.5.4).
(more details in std::initializer_list as function argument and Folds (ish) In C++11)
Moreover any {}
-list should be sequenced (the standard uses a very strong wording about this fact. See also http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1030).
So it's probably a GCC bug (fixed after gcc v4.9.0).
Indeed, trying various GCC version, I get:
GCC with --std=c++11 without (--std=c++98)
4.7.3 fg gf <-
4.8.1 fg gf <-
4.8.2 fg gf <-
4.9.0 fg gf <-
4.9.2 fg fg
5.1.0 fg fg
5.2.0 fg fg
6.1.0 fg fg
Extended initializer lists are only available with C++11 but GCC compiles the code anyway (with a warning, e.g. see gcc -Wall -Wextra
vs gcc -Wall -Wextra -std=c++11
).
Why must initializer list order match member declaration order?
The warning is trying to prevent situations where you might be relying on the wrong ordering of the data members. Say you think B is initialized before A, and then you do something like this:
myClass::myClass() :
B(42), A(B) {}
Here, you have undefined behaviour because you are reading from an uninitialized B
.
Order of execution in constructor initialization list
According to ISO/IEC 14882:2003(E) section 12.6.2:
Initialization shall proceed in the following order:
- First, and only for the constructor of the most derived class as described below, virtual base classes shall
be initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph
of base classes, where “left-to-right” is the order of appearance of the base class names in the derived
class base-specifier-list.- Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list
(regardless of the order of the mem-initializers).- Then, nonstatic data members shall be initialized in the order they were declared in the class definition
(again regardless of the order of the mem-initializers).- Finally, the body of the constructor is executed.
So, follow that order, and you'll have your order. Also according to the standard, the order is prescribed as such so that objects can be uninitialized in the precisely reverse order.
Member initializer list. Order of arguments evaluation
No, this evaluation order that would potentially cause you to leak is guaranteed not to happen. The expression within each mem-initializer is a full-expression ([intro.execution] §5.3). And [intro.execution] §9 tells us
Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.
So in other words, the evaluation of each expression used to initialize a member is completed before evaluation of the expression for the next member starts.
Initializer list *argument* evaluation order
C++ Standard 12.6.2/3
:
There is a sequence point (1.9) after the initialization of each base and member. The expression-list of a mem-initializer is evaluated as part of the initialization of the corresponding base or member.
The order of the initialization is the one you specified in the question. Evaluation is part of this initialization, and the initializations can't interleave (because there is a sequence point between them).
That means that the function calls in your initializer lists are not called in the desired order, but in the order in which the member declarations appear.
List evaluation order in constructor initialization
sub-object destructors should always be called in reverse order compared to sub-object constructors (otherwise way too many things will fall apart)
There can be multiple constructors of the object, each with it's own order of sub-objects in the list
If we call sub-object constructors in the order which is specific to each object constructor, we won't be able to get one single order for sub-object destructors.
Hence, the decision to have in the order of declaration, which doesn't depend on the order of sub-objects in different object constructors.
List evaluation order in constructor initialization
sub-object destructors should always be called in reverse order compared to sub-object constructors (otherwise way too many things will fall apart)
There can be multiple constructors of the object, each with it's own order of sub-objects in the list
If we call sub-object constructors in the order which is specific to each object constructor, we won't be able to get one single order for sub-object destructors.
Hence, the decision to have in the order of declaration, which doesn't depend on the order of sub-objects in different object constructors.
Is the order of variable used in constructor initialization list important?
Do we have to use variables in initialization list in the same order as we declared in class?
Order of initialization list doesn't have impact on initialization order. So it avoids misleading behavior to use real order in initialization list.
Problem comes when there is dependencies:
class A
{
int a;
double b;
float c;
// initialization is done in that order: a, b, c
A():a(1), c(2), b(c + 1) // UB, b is in fact initialized before c
{}
};
Will the order of variables in initialization list has any impact on memory allocation of that class/variables?
Order of initialization list doesn't have impact on layout or in initialization order.
Order of member initialization list
Initialization of member variables occurs in the order that they are declared in the class.
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-order
and:
http://en.cppreference.com/w/cpp/language/initializer_list
3) Then, non-static data members are initialized in order of
declaration in the class definition.
Related Topics
Finding the Type of an Object in C++
Opencv Point(X,Y) Represent (Column,Row) or (Row,Column)
Declaring Pointers; Asterisk on the Left or Right of the Space Between the Type and Name
C and C++: Partial Initialization of Automatic Structure
Advantage of Switch Over If-Else Statement
Concurrency: Atomic and Volatile in C++11 Memory Model
When Should I Make Explicit Use of the 'This' Pointer
Does the Size of an Int Depend on the Compiler And/Or Processor
Initialize Static Variables in C++ Class
C++11 Make_Pair With Specified Template Parameters Doesn't Compile
What Are Template Deduction Guides and When Should We Use Them
Why Pass by Const Reference Instead of by Value
Is It Safe to Delete a Void Pointer
C++ Static Initialization Order