有未初始化的变量和编译器(GCC) [英] Fun with uninitialized variables and compiler (GCC)

查看:176
本文介绍了有未初始化的变量和编译器(GCC)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++标准中的§3.9.1/ 6部分说,


bool类型的值为 true false


此代码

  void f(bool b)
{
switch是bool,它的值可以是true或false!
{
case true:cout<< 可能值 - 真;打破;
case false:cout<< 可能值 - 假;打破;
default:cout<< 不可能值;
}
}
int main()
{
bool b; // note:b is uninitialized
f(b);
return 0;
}

编译 F:\workplace> g ++ test。 cpp -pedantic



运行。输出:


不可能的值


输出?好吧,不是真的,正如标准在§3.9.1/ 6的脚注中所说:


使用bool值描述
作为
未定义(例如)检查
未初始化
自动对象的价值
b可能会导致表现为
既非true也不是false


无论我编译和运行这个程序多少次,我得到相同的输出:不可能的值。然而,如果我改变它一点 - 从图片中删除函数 f(),并写入开关 main()本身:

  b {
bool b; // note:b未初始化
switch(b)//因为b是bool,它的值可以是true或false!
{
case true:cout<< 可能值 - 真;打破;
case false:cout<< 可能值 - 假;打破;
default:cout<< 不可能值;
}
return 0;
}

然后我编译并运行这个程序, $ c>不可能值作为输出;无论多少次我重复这个,我从来没有得到不可能的值。



我只是想知道为什么这个突然改变的未初始化bool的行为?



好吧,从语言的角度来看,很清楚:行为是未定义的。我也理解编译器是免费做任何事情。然而,从编译器的角度来看,这似乎对我很有趣。



我使用的是: g ++ (GCC)4.5.0 - MinGW,在Windows 7 Basic,64位操作系统

解决方案


我只是想知道为什么这个突然改变的未初始化bool的行为?


代码,看看编译器是做什么的。



我的猜测:由于该值现在只在本地使用,编译器优化它完全。由于行为是未定义的,编译器可以安全地假设任何值,例如。 false 。这是一个非常明显的优化,因为对于编译器, b 的值是常量,并且 switch 是冗余的。那么为什么把它放在可执行文件中呢?



(这里的重点是 b 在第二个代码中,并且反过来将触发更多的优化,即使在未优化的代码中。第一个代码必须在编译器可以做任何这样的优化之前内联,或者代码路径必须被跟踪,这不是微不足道的) / p>

The section §3.9.1/6 from the C++ Standard says,

Values of type bool are either true or false.

Now consider this code,

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;
}

Compile F:\workplace>g++ test.cpp -pedantic

Run. Output :

impossible value

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.

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;
}

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.

I'm just curious to know why this sudden change in the behavior of uninitialized bool?

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?

I'm using : g++ (GCC) 4.5.0 - MinGW, on Windows 7 Basic, 64-bit OS.

解决方案

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.

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?

(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).

这篇关于有未初始化的变量和编译器(GCC)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆