局部作用域变量是初始化为未确定的值,还是未初始化?

Is a local scoped variable initialized to an undetermined value, or un-initialized?

提问人:Luchian Grigore 提问时间:9/23/2014 更新时间:9/24/2014 访问量:103

问:

迂腐地说,是否在下面的代码中初始化?x

int main()
{
    int x;
}

在 8.5 初始化器 [dcl.init](用于 C++11)中有一些关于它的段落,但没有任何示例支持。

C++ 语言律师

评论

4赞 Captain Obvlious 9/23/2014
简短的回答,不。长答案,不。
2赞 dyp 9/23/2014
它是默认初始化的。这意味着不执行初始化 (for )。int
0赞 Deduplicator 9/23/2014
因此,它保持不确定,因此读取它(因为它是自动存储类)是 UB。

答:

5赞 dyp 9/23/2014 #1

它是正式默认初始化的,这意味着对于 s,不执行任何初始化。int

[dcl.init]/12 (N3797)

如果未为对象指定初始值设定项,则该对象将默认初始化;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值

[dcl.init]/7

默认初始化类型的对象意味着:T

  • if 是(可能是 CV 限定的)类类型,默认值 构造函数称为 [...];TT

  • 如果是数组类型,则每个元素都是默认初始化的;T

  • 否则,不执行初始化

评论

3赞 Yakk - Adam Nevraumont 9/23/2014
因此,它被初始化,但该操作包括“不执行初始化”。要么是这样,要么是默认初始化的,但在这种情况下,默认初始化不是一种初始化。或者,术语“初始化”在标准中没有正式含义,而“默认初始化”与“执行初始化”一样。嘎。
0赞 dyp 9/23/2014
@Yakk 没错。让我想起了无法完成的完整类型。
0赞 Deduplicator 9/23/2014
@Yakk:因此,它保持不确定是事实正确的,并且是其状态的标准一致措辞。因此,如果它是自动存储类,则根据 4.1 lvalue-to-rvalue-conversion [conv.lval] 使用 UB。
0赞 Shafik Yaghmour 9/24/2014
@Deduplicator值得庆幸的是,在 C++14 中,我们不需要依赖 L 到 R 的转换来了解这种未定义的行为。
3赞 Columbo 9/23/2014 #2

不,不是。根据标准,默认初始化 ([dcl.init]/6):x

默认初始化 T 类型的对象意味着:

— 如果是(可能是 CV 合格的)类类型 [...]T

— if 是数组类型 [...]T

否则,不执行任何初始化

x因此,由于未执行初始化,因此未初始化。
因此,该对象具有不确定的值 ([dcl.init]/11):

如果未为对象指定初始值设定项,则该对象为 默认初始化;如果未执行初始化,则对象 具有自动或动态存储持续时间的不确定值。

此外,如果我们要访问它存储的不确定值 - 换句话说,对它执行左值到右值的转换 - 我们将诱发未定义的行为 ([conv.lval]/1]):

如果 glvalue 所指的对象是 [..],或者如果 未初始化,则需要此转换的程序具有 未定义的行为

2赞 Abdulrahman Alhadhrami 9/24/2014 #3

我的理解是,变量 x 在内存中的位置是保留的,但未设置为值(未初始化)。因为它是未初始化的,所以那里的任何旧值都将被视为 'garbage' int。