Is this behavior well-defined?
class Foo
{
int A, B;
public:
Foo(int Bar): B(Bar), A(B + 123)
{
}
};
int main()
{
Foo MyFoo(0);
re
No, initialization order is defined by the declaration order in the class itself.
From the C++ standard 12.6.2 [class.base.init] p5
:
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.
[Note: the declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. ]
Initialization is done in the order of appearance in the declaration, not the order you write it in the constructor.
Look at this question, it's somewhat similar: Initializer list *argument* evaluation order
No, it's undefined. A
will be initialized first (it's first in the class definition), and it uses uninitialized B
.
Class members are initialized in the order they appear in the class definition, irrespective of their order in the initialization list. Indeed, it is bad practice to mismatch the member definition order with the initialization list order.
If your instance of Foo
happened to have static duration, like in Foo f(0); int main(){}
, the behavior is well-defined. Objects with static duration are zero-initialized before any other initialization takes place; in that case, A
and B
will be 0 when the constructor is run. After that, though, the behavior is the same: first A
then B
, giving A
a value of 123 and B
a value of Bar
(still ugly).