Reputation: 3880
For example:
Cls::Cls(int *p) : m1_(1), m2_(m1), m3_(p), m4_(m3) {}
where Cls::m1_
and Cls::m2_
are of type int
and m3
and m4
are of type int*
.
Is this legal? If it is legal, does it do what one would expect?
Upvotes: 2
Views: 90
Reputation: 1611
Yes, it's legal. The init order follows the order of the members in the class.
struct C
{
C() : m1_(1), m2_(m1_ + 1), m3_(m2_ + 2), m4_(m3_ + 3) {}
int m1_ = 0;
int m2_ = 0;
int m3_ = 0;
int m4_ = 0;
};
int main()
{
C c;
std::cout << c.m1_ << std::endl;
std::cout << c.m2_ << std::endl;
std::cout << c.m3_ << std::endl;
std::cout << c.m4_ << std::endl;
}
The output:
1
2
4
7
But if you modified the member orders:
struct C
{
C() : m1_(1), m2_(m1_ + 1), m3_(m2_ + 2), m4_(m3_ + 3) {}
int m2_ = 0;
int m3_ = 0;
int m4_ = 0;
int m1_ = 0;
};
The output will be:
1
1
3
6
Upvotes: 3
Reputation: 180490
This is legal-ish. If you have
struct foo
{
int a;
int b;
int c;
foo() : a(1), b(a + 1), c(b + 1) {}
};
Then this is fine. The reason is a
is declared in the class before b
and b
is declared before c
. All class members are initialized in the order they are declared in the class, so you could even have
struct foo
{
int a;
int b;
int c;
foo() : c(b + 1), b(a + 1), a(1) {}
};
and you would still be okay. If you had
struct foo
{
int b;
int c;
int a;
foo() : a(1), b(a + 1), c(b + 1) {}
};
on the other hand, both b
and c
would be initialized with an indeterminate value and using them would be undefined behavior.
Upvotes: 2
Reputation: 119089
As pointed out in the comments, non-static data members are initialized in declaration order. In order to prevent confusion, you should always write the member initializers in declaration order. In the case presented in the question, I will therefore assume that the order in which the members were declared is:
int m1_;
int m2_;
int* m3_;
int* m4_;
Assuming that is the case, the code is well-defined and does what you expect it to do. This is guaranteed by [intro.execution]/12.3, which guarantees that each member initialization is a full-expression, and [class.base.init]/13.3, which guarantees that these initializations occur in declaration order.
Upvotes: 2