我清楚了解了我对价值初始化与默认初始化的理解,并且遇到了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 ();
答案 0 :(得分:13)
您的第一个示例具有未定义的行为,因为默认的编译器
生成的复制构造函数将执行成员复制,int
可能有
捕获值,并读取捕获值以复制它可能会导致
程序崩溃。
在实践中,我无法想象这实际上会崩溃;编译器 几乎肯定会优化副本,即使它没有,它 可能会使用一些特殊的按位复制,无需复制 检查陷阱值。 (在C ++中,您可以保证能够 复制字节。)
对于第二种情况,再次,未定义的行为。虽然在这种情况下, 你有赋值而不是复制构造,编译器是 不太可能优化它。 (你的第一个没有作业 例如,只复制构造。)
对于第三个,是的。一个带有空括号的初始化程序(并且没有 用户定义的默认初始化程序来覆盖它)首先执行零 初始化(与具有静态生命周期的变量完全相同)。
答案 1 :(得分:1)
尽管undefined behavior
中的值为c
,但我认为这实际上并不是unspecified values
。也就是说,只要您不使用这些未指定的值,程序的行为就会很明确。如果您使用它们,例如在条件或打印它们时,结果未定义。但是,我不认为该计划可以做任何奇怪的事情。
关于在内置类型上使用默认构造函数,这可以保证产生类型的零值,即整数为0
,浮点类型为0.0
等。这也扩展到没有构造函数的类型的成员。一旦有任何构造函数,你需要在没有构造函数的情况下自己构建你的成员。
答案 2 :(得分:-1)
没有。会发生什么是大多数编译器会优化变量输出的设置,但那些不会改变x的值。它与以下代码相同:
int x = 0;
x = 0;
不是第二行不会执行,它不会做任何事情。