问题是在答案的评论中出现的 当Typecast'到INT时,C/C ++ Bool类型是否总是保证为0或1?

所讨论的代码分配了一个(本地)数组 bool 不初始化其价值。

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

清楚地中的价值 b 不确定。

一些评论者认为阅读 b[0] 是不确定的行为。 C ++标准中的任何地方都说明了这一点吗?我仍然相信相反:

  1. 显然有分配的存储,并且基本布尔类型的初始化是完整的,因为它没有构造函数。因此,它肯定与取消非初始化的指针或在非初始化的非平凡对象上调用方法/铸造操作员并不相同。这些特定情况似乎已被标准涵盖。

  2. 在C中,这种行为确实是不确定的: 在C中宣布的,非初始化的变量会发生什么?它有价值吗? 一些受访者似乎使两者感到困惑。

  3. 在最新的C ++ 0x草稿中,我找不到 不确定的值 特别是没有定义可以允许访问该值以触发处理器陷阱的定义。的确,Bjarne Stroustrup不确定什么是差异值: http://zamanbakshifirst.blogspot.com/2007/02/c-indeterminate-value.html

有帮助吗?

解决方案

是的,正式的不确定值的rvalue转换为ub(除了 unsigned char, ,最初我写了“和变体”,但我记得正式的符合1的补语签名char,可能会将减去0用作陷阱值)

我太懒了,无法为您做标准的段落查找,也懒于关心下降投票

但是,实际上,(1)古老体系结构以及(2)64位系统中只有一个问题。

编辑: :糟糕,我现在似乎回想起有关正式UB访问不确定字符的博客发布和相关的缺陷报告。因此,也许我必须实际检查标准 +搜索DRS。 grh,现在必须稍后再咖啡!

Edit2: :约翰内斯·舒布(Johannes Schaub)很友善地提供了这个 链接到这样的问题 讨论了访问炭的UB的位置。所以,这就是我记得的地方!谢谢,约翰内斯。

欢呼和hth。

其他提示

这个问题的答案随着最新的C ++ 1Y工作草案而改变(N3946)我们可以找到 这里. 。部分 8.5 初始化器 段落 12 从C ++ 03和C ++ 11更改很多,现在包含以下(强调我的):

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

并继续列出一些例外 未签名的狭窄字符类型 只是,我有一个完整的报价 C ++ 1y是否在使用不确定的值和不确定的行为方面是否发生了变化?.

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

以前,我们需要使用LVALUE到RVALUE转换来证明这是不确定的,但这是有问题的,因为 转换被指定.

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

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

布尔类型的值是真或错误。

带有脚注说明:

以该国际标准描述的方式使用布尔价值 “不明确的,” 例如检查非初始化自动对象的价值,可能会导致其行为 好像这不是真的也不是错误的。

阅读不确定价值通常会导致不确定的行为这一事实不仅仅是一个“理论”问题。即使对于所有可能的位模式都定义值的类型,也不应将不确定值以不同于未指定值不同的方式行为不确定。例如,如果 *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占用的存储在释放和重新混合之前被“浮点”占据,则编译器可能会在上面的“如果”语句之间写入“ float”值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top