请让我们考虑以下代码:
#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没有被启动,任何编译器都可以认为它的值是零吗?我很好奇,请告诉我一些关于这个的事情,如果我的问题不清楚,我说,我不是英语母语人士。
答案 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;
表示联合中的x
和i
都已初始化。