2010-11-25 18 views
11

该问题出现在答案的评论的问题Is C/C++ bool type always guaranteed to be 0 or 1 when typecast'ed to int?正在读取一个不确定的值未定义的行为?

有问题的代码分配的bool(本地)阵列而不初始化它们的值。

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

很明显,b中的值是不确定的。

一些评论者认为阅读例如b[0]是未定义的行为。这是C++标准中的任何地方吗?我仍然相信相反的:

  1. 有明确的存储分配和基本布尔类型的初始化是完整的,因为它没有一个构造函数。因此,它肯定与取消引用未初始化的指针或调用未初始化的非重要对象上的方法/转换运算符相同。这些具体情况似乎已被标准覆盖。

  2. C:What happens to a declared, uninitialized variable in C? Does it have a value?中的行为确实未定义,有些受访者似乎混淆了这两者。

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

+1

呵呵,“未定义的行为”在StackOverflow中是一个非常喜欢的术语,它用于从定义的实现,直到未定义的实际定义。 – 2010-11-25 16:54:13

+1

我的意思是谚语中的“鼻魔”种类未定义。 – Sebastian 2010-11-25 16:57:30

回答

4

是,正式不定值的右值转换为UB(除unsigned char,原来我写了“及其变体”,但我记得的正式迎合了1的补符号的字符,其中有可能减0可以作为陷阱值)

我懒得做标准款查找适合你,也懒得计较downvotes为

然而,实际上在(1)古老的体系结构中,也许只是一个问题(2)64位系统。

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

EDIT2:Johannes Schaub非常友好地提供了这个link to SO question,其中讨论了访问字符的UB。所以,这就是我想起它的地方!谢谢,约翰内斯。 。

欢呼&心连心,

3

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

值是真或假 。

随着一个脚注:

的方式使用布尔值来描述 本国际标准如 “未定义”,例如通过检查一个未初始化的自动 对象的 值,可能会导致它表现为,就好像 它既不是真也不是假。

5

答案与最新的C++ 1Y工作草案(N3946),我们可以发现here这个问题的变化。部8.5初始化器段落从C++ 03和C++ 11改变了很多,现在包含以下(重点矿山):

如果对象没有指定初始化,则对象是默认初始化的 。 当获得用于与自动或 动态存储持续时间的对象存储,所述对象具有不确定 值,如果没有初始化为对象进行,即 对象保留一个不确定的值,直到该值被替换 (5.17)。 [注意:静态或线程存储时间为 零初始化的对象,请参见3.6.2。 - 注完] 如果一个不确定的值是通过评估产生 ,这种行为是未定义除了在 以下情况

,并继续列出一些例外无符号窄字符类型只,我有一个完整的报价Has C++1y changed with respect to the use of indeterminate values and undefined behavior?

所以你的情况b具有自动存储时间而没有初始化,因此具有不确定的值。因此评估b[0]确实是未定义的行为。

以前我们需要使用左值到右值转换证明,这是不确定的,但就是因为the conversion is underspecified问题。

注意,不确定的值本节斜体,因此这意味着它在适当的位置被限定,因此现在C++ 1Y实际上定义了术语。此前该术语没有定义,这在defect report 616中涵盖。

0

,阅读一个不确定的值通常会导致不确定的行为其实是不只是一个“理论”的问题。即使对于所有可能的位模式都具有已定义值的类型,对于不确定值的行为方式与未指定值不同,也不应将其视为“令人惊讶”。例如,如果* p成立不确定的值,而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的值是不确定的是,编译器不会禁止 让两个“if”语句之间的代码修改其值。 例如,如果* p占用的存储在释放并重新malloc之前被“float” 占用,编译器可能会在上述两个“if”语句之间写入“float” 值。

相关问题