Consider:
int f () {
static int i = 0;
return i++;
}
struct Test {
int a, b;
Test () : a(f()), b(f()) {}
};
Test t;
I know that a
is initialized before b
due to the order of their declaration in the struct
.
I also know that the two calls to f
in g(f(), f())
are unsequenced.
So I am wondering if it is guaranteed that t.a == 0
and t.b == 1
?
So I am wondering if it is guaranteed that
t.a == 0
andt.b == 1
?
This will always be true so long as a
comes before b
in the class declaration and nothing else calls f()
between the initialization of a
and b
. Class members are initialized in the order they are declared in the class. [class.base.init]/11:
In a non-delegating constructor, initialization proceeds in the following order: [...]
- 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).
So since a
comes before b
then when the constructor initializes a
it will call f()
the first time and then it will call it a second time when it initializes b
.
We also know there is a sequence point between member initializer because [class.base.init]/7:
[...]The initialization performed by each mem-initializer constitutes a full-expression. Any expression in a mem-initializer is evaluated as part of the full-expression that performs the initialization.
tells us each initializer is a full expression and each full expression is sequenced: [intro.execution]/14
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.