读取不确定值的未定义行为?

Seb*_*ian 11 c++ initialization undefined-behavior

这个问题出现在问题答案的评论中.当类型转换为int时,C/C++ bool类型总是保证为0或1吗?

有问题的代码在bool不初始化其值的情况下分配(本地)数组.

const int n = 100;
bool b[n];
Run Code Online (Sandbox Code Playgroud)

显然,价值观b是不确定的.

一些评论者认为阅读b[0]是不明确的行为.这是在C++标准中的任何地方陈述的吗?我仍然相信相反:

  1. 显然存储已分配,并且基本bool类型的初始化已完成,因为它没有构造函数.因此,它肯定与取消引用未初始化的指针或在未初始化的非平凡对象上调用方法/强制转换操作符不同.标准似乎涵盖了这些具体案例.

  2. C中的行为确实未定义:C中声明的未初始化变量会发生什么?它有价值吗?一些受访者似乎对这两者感到困惑.

  3. 在最新的C++ 0x草案中,我找不到不确定值的定义,尤其是没有允许访问这样的值来触发处理器陷阱的定义.事实上,Bjarne的Stroustrup的是不知道的inderminate值可能是什么:http://zamanbakshifirst.blogspot.com/2007/02/c-indeterminate-value.html

Che*_*Alf 6

是的,形式上不确定值的右值转换是 UB(除了unsigned char,最初我写了“和变体”,但我记得形式迎合了 1 的补码有符号字符,其中负 0 可能用作陷阱值)

我懒得为你做标准的段落查找,也懒得关心反对票

然而,实际上只有 (1) 过时的体系结构和 (2) 64 位系统存在问题。

编辑:哎呀,我现在似乎想起了一篇关于访问不确定字符的正式 UB 的博客帖子和相关的缺陷报告。所以也许我必须实际检查标准,+ 搜索 DR。啊,那得晚点了,现在喝咖啡!

EDIT2:Johannes Schaub 非常友​​好地提供了指向 SO 问题的链接,其中讨论了用于访问字符的 UB。所以,这就是我记得它的地方!谢谢,约翰内斯。

干杯 & hth.,

  • +1。4.1/1:“非函数、非数组类型 T 的左值 (3.10) 可以转换为右值。如果 T 是不完整的类型,则需要这种转换的程序是格式错误的。如果对象左值所指的不是 T 类型的对象,也不是从 T 派生的类型的对象,或者如果该对象未初始化,则需要进行此转换的程序具有未定义的行为。” (5认同)

Sha*_*our 6

这个问题的答案随着最新的C++ 1y工作草案(N3946)而改变,我们可以在这里找到.Section 8.5 Initializers12段从C++ 03和C++ 11改变很多,现在包含以下内容(强调我的):

如果没有为对象指定初始化程序,则默认初始化该对象.当获得具有自动或动态存储持续时间的对象的存储时,该对象具有 不确定的值,并且如果没有对该对象执行初始化,则该对象保留不确定的值,直到该值被替换(5.17).[注意:具有静态或线程存储持续时间的对象是零初始化的,请参见3.6.2.- 结束注释] 如果评估产生不确定的值,则行为是不确定的,除非在以下情况中:

并继续列出一些无符号窄字符类型的例外情况,我在Has C++ 1y中有一个完整的引用,关于使用不确定的值和未定义的行为?.

因此,在您的情况下b具有自动存储持续时间并且未初始化,因此具有不确定的值.所以评估b[0]确实是未定义的行为.

以前我们需要使用左值到右值的转换来证明这是未定义的,但这是有问题的,因为转换是未指定的.

请注意,本节中的不确定值是斜体,因此它意味着它正在定义,因此现在C++ 1y实际上定义了该术语.以前该术语在没有定义的情况下使用,这在缺陷报告616中有所涉及.


Unc*_*ens 5

在上bool,标准在3.9.1基本类型下说:

bool类型的值为true或false。

脚注说明:

以本国际标准描述为“未定义”的方式使用布尔值 例如通过检查未初始化的自动对象的值,可能会导致其行为既不正确也不错误。


归档时间:

查看次数:

1501 次

最近记录:

10 年,1 月 前