Member initialization out of order - is this normal?

From the comment of this answer :

Class members are initialized in the order they are declared. By this logic, the following constructor should refer to undefined behavior:

struct Foo { Bar a; Bar b; Foo(Bar c) : a(b = c) { } }; 

Apparently, we assign b before a is initialized. Assignment to an uninitialized object must be UB. Not surprisingly, the code “works” with Bar = int , but if I make Bar heavy class with constructors, I see that b really initialized to a .

(For superfluous madness, we can even say Foo(Bar c, Bar d) : a(b = c), b(d) { } , still without warning.)

However, GCC 4.6.1 does not warn about this. Is this acceptable, well-defined behavior, or is it strictly wrong?

+4
source share
1 answer

Given Bar , where an uninitialized state really matters to the assignment operator, I get warnings from GCC:

 #include <iostream> struct Bar { int n; Bar(int v) : n(v) { std::cout << "Bar " << n << " constructed\n"; } Bar& operator=(const Bar& other) { std::cout << "Bar " << n << " assigned from " << other.n << "\n"; n = other.n; return *this; } }; struct Foo { Bar a; Bar b; Foo(Bar c, Bar d) : a(b = c), b(d) { } }; int main() { Foo f(Bar(1), Bar(2)); } 

test: https://ideone.com/VDZzG

 test.cc: In function 'int main()': test.cc:8:32: warning: '*((void*)(& f)+4).Bar::n' is used uninitialized in this function [-Wuninitialized] test.cc:23:13: note: '*((void*)(& f)+4).Bar::n' was declared here 

The other compilers I tried apparently don't care though ...

+4
source

Source: https://habr.com/ru/post/1379569/


All Articles