【问题标题】:Why the default value of automatic variable is 0 instead of garbage one? [duplicate]为什么自动变量的默认值是 0 而不是垃圾 1? [复制]
【发布时间】:2016-06-25 04:55:13
【问题描述】:

考虑一下代码sn-p:

int main()  
{
int n;
cout<<n;
float f;
cout.setf(ios_base::fixed,ios_base::floatfield);
cout<<endl<<f;
char ch;
cout<<endl<<static_cast<int>(ch);
return 0;
}

输出:

0
0.000000
0

为什么它没有设置为垃圾值而不是零?这是未定义行为的结果吗?在Ubuntu 14.04 上使用g++4.8.2 编译。

【问题讨论】:

  • 零是一个完全有效的“垃圾”数字,在任何情况下它都是未定义的行为,如果需要,您的实现可以打印“foobar”。
  • 虽然很难用数字打印“foobar”
  • -O3编译,你可能会得到不同的结果

标签: c++ variables c++11


【解决方案1】:

这是特定于编译器和选项的效果。

静态变量首先是零初始化的。自动局部变量没有这样的保证初始化。但是编译器可以添加零初始化,只是为了“有帮助”。

您意外地正确,对于呈现的代码,0 结果是“未定义行为的结果”。但这只是因为使用 int 类型的不确定值是未定义的行为,或者至少是 UB 直到并包括 C++11。有点不清楚访问三个基本 char 类型之一的不确定值是否是 UB:有一些关于它的缺陷报告(DR #240#616),C++14 的措辞不同于C++11 及更早版本,似乎将 UB 的规范移至标准的其​​他部分。

【讨论】:

    【解决方案2】:

    您应该记住,C++11 标准中定义的自动变量没有默认初始值。

    实际上,这样的变量会包含一些垃圾值(如果它位于处理器寄存器中,则为它的前一个值;如果它位于调用堆栈的一个槽中,则为该位置的前一个值),这可能是0(或其他)。

    详细信息是特定于实现的,会因编译器、运行、优化标志而异。

    阅读 undefined behavior,尤其是 Lattner 的博客:What every programmer should know about undefined behavior。成为他们中的真正scared

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-14
      • 2014-01-29
      • 1970-01-01
      • 2012-12-21
      相关资源
      最近更新 更多