为什么这个简单的赋值是未定义的行为?

时间:2012-02-06 16:33:31

标签: c++ undefined-behavior value-initialization

我清楚了解了我对价值初始化与默认初始化的理解,并且遇到了this

struct C {
    int x;
    int y;
    C () { }
};

int main () {
    C c = C ();
}

显然这是UB,因为

  

在C()的情况下,有一个能够的构造函数   初始化x和y成员,因此不会进行初始化。   因此,尝试将C()复制到c会导致未定义的行为。

我想我理解为什么,但我不确定。有人可以详细说明吗?

这是否意味着这也是UB?

int x; x = x;

顺便提一下,关于值初始化,以下是否保证为零?

int x = int ();

3 个答案:

答案 0 :(得分:13)

您的第一个示例具有未定义的行为,因为默认的编译器 生成的复制构造函数将执行成员复制,int可能有 捕获值,并读取捕获值以复制它可能会导致 程序崩溃。

在实践中,我无法想象这实际上会崩溃;编译器 几乎肯定会优化副本,即使它没有,它 可能会使用一些特殊的按位复制,无需复制 检查陷阱值。 (在C ++中,您可以保证能够 复制字节。)

对于第二种情况,再次,未定义的行为。虽然在这种情况下, 你有赋值而不是复制构造,编译器是 不太可能优化它。 (你的第一个没有作业 例如,只复制构造。)

对于第三个,是的。一个带有空括号的初始化程序(并且没有 用户定义的默认初始化程序来覆盖它)首先执行零 初始化(与具有静态生命周期的变量完全相同)。

答案 1 :(得分:1)

尽管undefined behavior中的值为c,但我认为这实际上并不是unspecified values。也就是说,只要您不使用这些未指定的值,程序的行为就会很明确。如果您使用它们,例如在条件或打印它们时,结果未定义。但是,我不认为该计划可以做任何奇怪的事情。

关于在内置类型上使用默认构造函数,这可以保证产生类型的零值,即整数为0,浮点类型为0.0等。这也扩展到没有构造函数的类型的成员。一旦有任何构造函数,你需要在没有构造函数的情况下自己构建你的成员。

答案 2 :(得分:-1)

没有。会发生什么是大多数编译器会优化变量输出的设置,但那些不会改变x的值。它与以下代码相同:

int x = 0;
x = 0;

不是第二行不会执行,它不会做任何事情。