无序初始化成员 - 这样可以吗?

时间:2011-11-04 00:21:04

标签: c++ constructor initializer-list

来自对this answer的评论:

类成员按其声明顺序初始化。通过这种逻辑,以下构造函数应该调用未定义的行为:

struct Foo
{
   Bar a;
   Bar b;

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

很明显,我们在b初始化之前首先分配给a。分配给未初始化的对象应该是UB。代码与Bar = int“一致”并不奇怪,但如果我使Bar成为构造函数的重类,我会发现b确实在a之前初始化了。

(对于额外的精神错乱,我们甚至可以说Foo(Bar c, Bar d) : a(b = c), b(d) { },仍然没有任何警告。)

然而GCC 4.6.1并没有对此发出警告。这是可接受的,定义明确的行为,还是严格错误?

1 个答案:

答案 0 :(得分:4)

给定Bar非初始化状态对赋值运算符实际上很重要,我收到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));
}

测试: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

我试过的其他编译器似乎并不关心,但是......