Consider the following code:
struct Foo{
std::string s1;
std::string s2;
};
int main(){
Foo f{.s1 = "s1", .s2 = f.s1 + "s2"};
std::cout << "s1='" << f.s1 << "', s2='" << f.s2 << "'" << std::endl;
}
Especially note that the initialization of s2
accesses the first member of f
: .s2 = f.s1 + "s2"
.
The latest clang, gcc and MSVC are happy with the code and give the naively expected result (they print "s1='s1', s2='s1s2'"
). See live on godbolt.
Question: Is this legal?
In other words, does the standard guarantee that f.s1
gets initialized before the designated initializer .s2
is evaluated?
Related: There is a similar question asking about whether .s2 = .s1 + "s2"
is legal, which clearly isn't, because it does not compile. Also, P0328 (as per this answer) might be relevant, but I can't see my question being answered there.
s1
is declared befores2
(inFoo
) so they will be initialized in the same order of declaration. The same applies in constructor initializer list by the way. – DelveFoo() : s1("foo"),s2(s1) {}
would be fine, whereasFoo() : s1(s2) , s2("foo") {}
not – Hepsibah