有趣的未初始化变量和编译器 (GCC)
C++ 标准的第 3.9.1/6 节说,
The section §3.9.1/6 from the C++ Standard says,
bool 类型的值为 true
或 false
.
Values of type bool are either
true
orfalse
.
现在考虑这段代码,
void f(bool b)
{
switch(b) //since b is bool, it's value can be either true or false!
{
case true: cout << "possible value - true"; break;
case false: cout << "possible value - false"; break;
default: cout << "impossible value";
}
}
int main()
{
bool b; //note : b is uninitialized
f(b);
return 0;
}
编译F:workplace>g++ test.cpp -pedantic
运行.输出:
不可能的值
意外的输出?好吧,并非如此,正如标准在 §3.9.1/6 的脚注中所说:
Unexpected output? Well, not really, as the Standard reads in the footnote of §3.9.1/6 that:
以描述的方式使用布尔值由本国际标准作为未定义",例如 通过检查未初始化的自动对象,可能会导致它表现得好像它是非真非假.
Using a bool value in ways described by this International Standard as "undefined," such as by examining the value of an uninitialized automatic object, might cause it to behave as if it is neither true nor false.
所以无论我编译和运行这个程序多少次,我都会得到相同的输出:impossible value
.但是,如果我稍微改变一下 - 从图片中删除函数 f()
,并在 main()
本身中编写 switch
块:
So no matter how many times I compile and run this program, I get the same output : impossible value
. However, if I change it a bit - removing the function f()
from the picture, and write the switch
block in main()
itself:
int main()
{
bool b; //note : b is uninitialized
switch(b) //since b is bool, it's value can be either true or false!
{
case true: cout << "possible value - true"; break;
case false: cout << "possible value - false"; break;
default: cout << "impossible value";
}
return 0;
}
然后我编译并运行这个程序,我没有得到 impossible value
作为输出;无论我重复多少次,我都不会得到不可能的值
.
Then I compile and run this program, I don't get impossible value
as output; no matter how many times I repeat this, I never get impossible value
.
我只是想知道为什么未初始化的 bool 的行为会突然发生这种变化?
I'm just curious to know why this sudden change in the behavior of uninitialized bool?
嗯,从语言的角度来看,很清楚:行为是未定义的.我明白这一点.我也明白编译器可以自由地做任何事情.然而,从编译器的角度来看,这对我来说似乎很有趣.编译器(即 GCC)在每种情况下可能会做什么?为什么?
Well, from the language perspective it's clear : the behavior is undefined.I understand that. I also understand the compiler is free to do anything. From the compiler perspective, however, this seems very interesting to me. What could the compiler (i.e GCC) possibly do in each case and why?
我正在使用:g++ (GCC) 4.5.0 - MinGW,在 Windows 7 Basic,64 位操作系统上
.
推荐答案
我只是想知道为什么未初始化的 bool 的行为会突然发生这种变化?
I'm just curious to know why this sudden change in the behavior of uninitialized bool?
反汇编代码,看看编译器在做什么.
Disassemble the code and see what the compiler’s doing.
我的猜测:由于该值现在仅在本地使用,编译器将其完全优化掉.由于无论如何行为是未定义的,编译器可以安全地假设任何值,例如假
.这是一个非常明显的优化,因为就编译器而言,b
的值是恒定的,而 switch
的整个逻辑是多余的.那么为什么要把它放在可执行文件中呢?
My guess: since the value is now only used locally, the compiler optimizes it away completely. Since the behaviour is undefined anyway, the compiler can safely just assume any value, e.g. false
. This is a pretty obvious optimization since the value of b
is constant as far as the compiler is concerned, and the whole logic of the switch
is redundant. So why put it in the executable?
(这里的重点是 b
只在第二个代码中本地使用,这反过来会触发更多优化,即使在未优化的代码中.第一个代码必须在之前内联编译器可以进行任何此类优化,或者必须跟踪代码路径,这不是微不足道的).
(The important point here is really that b
is only ever used locally in the second code, and that in turn will trigger more optimizations even in unoptimized code. The first code has to be inlined before the compiler can do any such optimizations, or the code paths have to be traced which isn’t trivial).
相关文章