这个问题的答案的评论中出现了这个问题 在对int进行类型转换时,C / C ++ bool类型总是保证为0或1吗?
有问题的代码分配一个(本地)数组 bool
没有初始化他们的价值。
const int n = 100;
bool b[n];
显然,价值观 b
是不确定的。
一些评论者认为阅读,例如 b[0]
未定义的行为。这是在C ++标准中的任何地方陈述的吗?我仍然相信相反:
显然存储已分配,并且基本bool类型的初始化已完成,因为它没有构造函数。因此,它肯定与解除引用未初始化的指针或在未初始化的非平凡对象上调用方法/强制转换操作符不同。这些具体案例似乎包含在标准中。
C中的行为确实未定义: 在C中声明的未初始化变量会发生什么?它有价值吗? 一些受访者似乎对这两者感到困惑。
在最新的C ++ 0x草案中,我找不到任何定义 不确定的价值 特别是没有允许访问这样的值来触发处理器陷阱的定义。实际上,Bjarne Stroustrup不确定什么是inderminate值可能是: http://zamanbakshifirst.blogspot.com/2007/02/c-indeterminate-value.html
是的,正式地,不确定值的右值转换是UB(除了 unsigned char
,最初我写了“和变种”,但我记得正式迎合1的补充签名char,其中可能减去0可以用作陷阱值)
我懒得为你做标准的段落查找,也懒得去关心它的downvotes
然而,实际上只有(1)古老架构和(2)64位系统的问题。
编辑:oops,我现在似乎回想起一篇关于正式UB访问不确定字符的博客文章和相关的缺陷报告。所以也许我必须实际检查标准,+搜索DR。唉,它必须晚些时候,现在咖啡!
EDIT2:Johannes Schaub非常友好地提供了这个 链接到SO问题 讨论了用于访问char的UB的位置。所以,这就是我记得的地方!谢谢,约翰内斯。
干杯和hth。,
这个问题的答案随着最新的C ++ 1y工作草案而改变(N3946
)我们可以找到 这里。部分 8.5
初始化器 段 12 从C ++ 03和C ++ 11变化很多,现在包含以下内容(强调我的):
如果没有为对象指定初始化程序,则该对象为
默认初始化。 使用自动或自动存储对象时
获得动态存储持续时间,该对象具有 不定
值,如果没有对该对象执行初始化,那
对象保留不确定的值,直到替换该值
(5.17)。 [注意:具有静态或线程存储持续时间的对象是
零初始化,见3.6.2。 - 结束说明] 如果是不确定的值
通过评估产生,行为是不确定的,除了在
以下案例:
并继续列出一些例外 无符号窄字符类型 只有,我有一个完整的引用 C ++ 1y在使用不确定值和未定义行为方面有变化吗?。
所以在你的情况下 b
具有自动存储持续时间并且未初始化,因此具有不确定的值。所以评估 b[0]
确实是未定义的行为。
以前我们被要求使用左值到右值的转换来证明这是未定义的,但这是有问题的,因为 转换是不明确的。
请注意,本节中的不确定值是斜体,因此它意味着它已在适当的位置定义,所以现在C ++ 1y实际上定义了该术语。以前使用的术语没有定义,这包括在内 缺陷报告616。
上 bool
,标准说下 3.9.1基本类型:
bool类型的值为true或
假。
用脚注说明:
以所描述的方式使用bool值
按此国际标准
“未定义” 比如通过检查
未初始化的自动值
对象,可能会导致它表现 仿佛
它既不是真也不是假。
阅读不确定值通常导致未定义行为的事实不仅仅是一个“理论”问题。即使对于所有可能的位模式都有定义值的类型,对于不确定值的行为方式也不应该被认为是“令人惊讶的”,其方式与未指定的值不同。例如,如果* 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占用的存储空间被“浮动”占用
在它释放并重新malloc之前,编译器可能会写“浮动”
上面两个“if”语句之间的值。