11

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

有问题的代码分配了一个(本地)数组bool而不初始化它们的值。

const int n = 100;
bool b[n];

显然,其中的值b是不确定的。

一些评论者认为阅读 egb[0]是未定义的行为。这在 C++ 标准中的任何地方都有说明吗?我仍然坚信相反的观点:

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

  2. 这种行为在 C 中确实是未定义的:在 C中声明的、未初始化的变量会发生什么?它有价值吗?一些受访者似乎混淆了这两者。

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

4

4 回答 4

6

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

我懒得为你做标准段落查找,也懒得关心否决票

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

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

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

干杯&hth.,

于 2010-11-25T16:54:10.190 回答
6

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

如果没有为对象指定初始化程序,则该对象是默认初始化的。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有 不确定的值,如果没有对该对象执行初始化,则该对象将保留一个不确定的值,直到该值被替换(5.17)。[ 注意:具有静态或线程存储持续时间的对象是零初始化的,请参见 3.6.2。— 尾注]如果评估产生不确定的值,则行为未定义,但以下情况除外

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

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

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

请注意,indeterminate value 在本节中用斜体表示,因此这意味着它正在就地定义,因此现在 C++1y 实际上定义了该术语。以前该术语在没有定义的情况下使用,这在缺陷报告 616中进行了介绍。

于 2014-05-02T13:34:25.950 回答
5
于 2010-11-25T18:22:45.287 回答
1

读取不确定值通常会导致未定义行为这一事实不仅仅是一个“理论”问题。即使对于所有可能的位模式都已定义值的类型,也不应将不确定值的行为方式与未指定值不同的方式视为“令人惊讶”。例如,如果 *p 持有 Indeterminate Value,并且 x 未在任何地方使用,除非如图所示,则代码:

uint32_t x,y,z;
...
x = *p;
if (condition1) y=x;
... code that "shouldn't" affect *p if its value is defined
if (condition2) z=x;

可以改写为:

if (condition1) y=*p;
... code that "shouldn't" affect *p if its value is defined
if (condition2) z=*p;

如果 *p 的值是 Indeterminate,则不会禁止编译器让两个“if”语句之间的代码修改其值。例如,如果 *p 占用的存储空间在它被释放和重新分配之前被一个“float”占用,编译器可能会在上面的两个“if”语句之间写入这个“float”值。

于 2016-05-07T16:17:10.113 回答