联合的默认值是否为零?

时间:2011-10-13 08:17:52

标签: c++

请让我们考虑以下代码:

#include <iostream>
using namespace std;

union{
 int i;
}u;

int main(){

     int k=5;
     cout<<k+u.i<<endl;

    system("PAUSE");
    return EXIT_SUCCESS;
}

此代码显示输出5,对我来说意味着,联合结构中的变量i具有默认值= 0,但ideone.com上的相同代码显示此类警告

prog.cpp:6: warning: non-local variable ‘<anonymous union> u’ uses anonymous type and then prints  5 as well, and last one  core of this problem comes  from algorithm calculate  

平方根的倒数,这里是代码

#include<iostream>
#include<math.h>
using namespace std;

float invsqrt(float x){

    float xhalf=0.5f*x;

    union{
         float x;
         int i;
    }u;

   u.x=x;
   u.i=0x5f3759df-(u.i>>1);
   x=u.x*(1.5f-xhalf*u.x*u.x);

   return x;
}

int main(){

    float  x=234;
    cout<<invsqrt(x)<<endl;

    return 0;
}

它也显示了我的输出,但我的问题是这个代码好吗?我的意思是因为int i没有被启动,任何编译器都可以认为它的值是零吗?我很好奇,请告诉我一些关于这个的事情,如果我的问题不清楚,我说,我不是英语母语人士。

3 个答案:

答案 0 :(得分:4)

  

联合的默认值是否为零?

语言标准说明了这一点:

  

如果未初始化具有静态或线程存储持续时间的对象   明确地说:

     
      
  • 如果它有指针类型,则将其初始化为空指针;
  •   
  • 如果它有算术类型,则初始化为(正数或无符号)零;
  •   
  • 如果是聚合,则根据这些规则初始化(递归)每个成员,   并且任何填充都被初始化为零位;
  •   
  • 如果它是一个联合,则根据这些初始化(递归)第一个命名成员   规则,任何填充都初始化为零位;
  •   

因此,在您的第一个代码示例中,u.i将初始化为零。

我根本不确定第二个代码示例。我看不出union那里的意思。我宁愿怀疑你打算使用struct而不是union。但请注意,这两个代码示例非常不同,因为此中的union具有静态存储持续时间,而在第二个union具有自动存储持续时间。这导致未初始化变量的语义完全不同。

答案 1 :(得分:1)

一般说明:警告 - 您似乎期望int成员以某种方式与union的float成员具有相同的大小。这可能是真的,但不是必须的。您似乎也假设您的编译器使用某个浮点表示。据我所知,编译器没有这样的义务 2

  

警告:非本地变量'u'使用匿名类型

只是意味着您不应该为外部可见符号使用匿名联合类型。如果您使用-Wall进行编译(所有警告都已开启),这也是您在本地也会看到的警告。

  

它也显示了我的输出,但我的问题是这个代码好吗?我的意思是因为int i没有被启动,任何编译器都可以认为它的值是零吗?

据我所看到的代码所示,u.i NOT 未初始化。根据您指定u.x的事实对其进行初始化。这是union的实际定义:union将成员字段存储在同一内存位置。这意味着,即使u.i可能(尚未检查)在0 1 处自动初始化,那么您将通过分配到u.x


<子> 1 (不太可能,因为编译器如何选择是否初始化.i或.x?)

2 虽然在实践中大多数都会使用IEEE格式(http://en.wikipedia.org/wiki/IEEE_754),因为大多数处理器本身支持

答案 2 :(得分:1)

这是初始化union变量:

union{
  float x;
  int i;
}u;
u.x=x;

表示联合中的xi都已初始化。