4

从对此答案的评论:

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

struct Foo
{
   Bar a;
   Bar b;

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

显然,我们在初始化b之前分配给第一个。a分配给未初始化的对象应该是 UB。代码“Bar = int工作”Bar与.ba

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

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

4

1 回答 1

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

不过,我尝试过的其他编译器似乎并不在意……

于 2011-11-04T04:53:42.993 回答