My assumption is that the code below ill-formed NDR? But why?
Your code has undefined behavior due to [class.base.init]/9
In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then
if the entity is a non-static data member that has a default member initializer ([class.mem]) and either
[...] the constructor's class is not a union [...]
the entity is initialized from its default member initializer as specified in [dcl.init];
So, that means
struct A{
int i = j + 1;
int j = 1;
};
is translated to
struct A{
A() : i(j + 1), j(1) {}
int i;
int j;
};
and since i
is initialized first it uses an uninitialized variable and is undefined behavior.
I think that the code is equal to following:
struct A{
int i;
int j;
A():i(j + 1),j(1){}
};
Which shows that the compilers are right. Because the members are initialized in the order (stated somewhere in the standard*) in which they were declared. The in-place declaration initialization should be just syntactic sugar for their initialization in all ctors. So, the code indeed has undefined behaviour because j
is an uninitialized variable.
EDIT: * Found it [10.9.2 Initializing bases and members] (http://eel.is/c++draft/class.base.init)
In a non-delegating constructor, initialization proceeds in the following order:
(13.1) First, and only for the constructor of the most derived class ([intro.object]), virtual base classes are 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 classes in the derived class base-specifier-list.
(13.2) Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
(13.3) 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).
(13.4) Finally, the compound-statement of the constructor body is executed.