这个问题出现在问题答案的评论中 当类型转换为 int 时,C/C++ bool 类型是否始终保证为 0 或 1?
相关代码分配一个 < 的(本地)数组code>bool 而不初始化它们的值。
const int n = 100;
bool b[n];
显然,b
中的值是不确定的。
一些评论者认为读取例如 b[0]
是未定义的行为。 C++ 标准中是否有这样的规定?我仍然相信相反的情况:
-
显然已经分配了存储空间,并且基本 bool 类型的初始化已经完成,因为它没有构造函数。因此,它肯定与取消引用未初始化的指针或在未初始化的非平凡对象上调用方法/强制转换运算符不同。标准似乎涵盖了这些特定情况。
-
该行为在 C 中确实未定义:C 中声明的、未初始化的变量会发生什么?它有价值吗?并且一些受访者似乎混淆了两者。
-
在最新的 C++0x 草案中,我找不到不确定值的定义,尤其是没有允许访问此类值来触发处理器陷阱的定义。事实上,Bjarne Stroustrup 不确定不确定值可能是什么:http: //zamanbakshifirst.blogspot.com/2007/02/c-independent-value.html
The question arose in the comments of an answer to the question Is C/C++ bool type always guaranteed to be 0 or 1 when typecast'ed to int?
The code in question allocates a (local) array of bool
without initializing their value.
const int n = 100;
bool b[n];
Clearly the values in b
are indeterminate.
Some of the commenters opined that reading e.g. b[0]
was undefined behavior. Is this stated anywhere in the C++ standard? I am still convinced of the opposite:
-
There is clearly storage allocated and initialization of the fundamental bool type is complete, since it doesn't have a constructor. It is thus certainly not the same as dereferencing an uninitialized pointer, or calling methods/cast operators on uninitialized non-trivial objects. These specific cases seem to be covered by the standard.
-
The behavior is indeed undefined in C: What happens to a declared, uninitialized variable in C? Does it have a value? and some respondents seem to confuse the two.
-
In the latest C++0x draft I can find no definition of indeterminate value especially no definition that would allow accessing such a value to trigger a processor trap. Indeed, Bjarne Stroustrup is not sure what an inderminate value may be: http://zamanbakshifirst.blogspot.com/2007/02/c-indeterminate-value.html
发布评论
评论(4)
是的,形式上不确定值的右值转换是 UB (除了
unsigned char
,最初我写的是“和变体”,但我记得形式迎合 1 的补码有符号字符,其中可能可以使用负 0作为陷阱值)我懒得为你做标准段落查找,也懒得关心对此的否决票,
但是,实际上只有(1)过时的架构,也许(2)64位上的问题系统。
编辑:哎呀,我现在似乎想起了一篇关于访问不确定字符的正式 UB 的博客文章和相关缺陷报告。所以也许我必须实际检查标准,+搜索DR。啊,那得晚点了,现在喝咖啡!
编辑2:Johannes Schaub很友善地提供了这个链接到SO问题,其中讨论了访问char的UB。所以,这就是我记得的地方!谢谢,约翰内斯。
干杯&呵呵,,
yes, formally an rvalue conversion of indeterminate value is UB (except for
unsigned char
, originally i wrote "and variants" but as i recall the formal caters to 1's complement signed char where possibly minus 0 could be used as trap value)i'm too lazy to do the standard paragraph lookup for you, and also to lazy to care about downvotes for that
however, in practice only a problem on (1) archaic architectures, and perhaps (2) 64-bit systems.
EDIT: oops, i now seem to recall a blog posting and associated Defect Report about formal UB for accessing indeterminate char. so perhaps i'll have to actually check the standard, + search DRs. argh, it will have to be later then, now coffee!
EDIT2: Johannes Schaub was kind enough to provide this link to SO question where that UB for accessing char was discussed. So, that's where I remembered it from! Thanks, Johannes.
cheers & hth.,
这个问题的答案随着最新的 C++1y 工作草案(
N3946
)而改变,我们可以在其中找到 此处。8.5
Initializers 段落 12 与 C++03 和 C++11 相比发生了很大变化,现在包含以下内容(强调我的):并继续列出一些仅无符号窄字符类型的例外情况,我在C++1y 在使用不确定值和未定义行为方面是否发生了变化? 。
因此,在您的情况下,
b
具有自动存储持续时间并且未初始化,因此具有不确定的值。因此评估b[0]
确实是未定义的行为。以前,我们需要使用左值到右值的转换来证明这是未定义的,但这是有问题的,因为 转换未指定。
请注意,不确定值在本节中以斜体显示,因此这意味着它是就地定义的,因此现在 C++1y 实际上定义了该术语。以前,该术语在没有定义的情况下使用,这在 缺陷报告616。
The answer to this question changes with the latest C++1y working draft(
N3946
) which we can find here. Section8.5
Initializers paragraph 12 changes a lot from C++03 and C++11 and now contains the following (emphasis mine):and goes on to list some exceptions for unsigned narrow character type only, I have a complete quote in Has C++1y changed with respect to the use of indeterminate values and undefined behavior?.
So in your case
b
has automatic storage duration and is not initialized and therefore has indeterminate value. So evaluatingb[0]
is indeed undefined behavior.Previously we were required to use the lvalue-to-rvalue conversion to prove this was undefined but that is problematic since the conversion is underspecified.
Note that indeterminate value is italicized in this section and therefore it means it is being defined in place and so now C++1y actually defines the term. Previously the term was used without a definition, this is covered in defect report 616.
对于
bool
,标准在 3.9.1 基本类型 下表示:脚注指出:
On
bool
, the standard says under 3.9.1 Fundamental types:With a footnote stating:
读取不确定值通常会导致未定义行为这一事实不仅仅是一个“理论”问题。即使对于所有可能的位模式都已定义值的类型,不确定值的行为方式与未指定值不同也不应被视为“令人惊讶”。例如,如果 *p 包含不确定值,并且 x 不在任何地方使用,除了
如图所示,代码:
可以重写为:
如果 *p 的值是不确定的,则不会禁止编译器
让两个“if”语句之间的代码修改其值。
例如,如果 *p 占用的存储空间被“float”占用
在释放和重新分配之前,编译器可能会写“float”
上面两个“if”语句之间的值。
The fact that reading an Indeterminate Value generally results in Undefined Behavior is not merely a "theoretical" issue. Even for types where all possible bit patterns have defined values, it should not be considered "surprising" for indeterminate values to behave in ways which differ from Unspecified values. For example, if *p holds Indeterminate Value, and x is not used anywhere except
as shown, the code:
could be rewritten as:
If the value of *p is Indeterminate, a compiler would not be forbidden
from having the code between the two "if" statements modify its value.
For example, if the storage occupied by *p was occupied by a "float"
before it freed and re-malloc'ed, the compiler might write that "float"
value between the two "if" statements above.