关于这段代码的简单问题:
union MyUnion
{
int a;
int b;
};
union MyUnion x, y;
x.a = 5;
y.b = 2;
y.a = 3;
x.b = 1;
int c = (x.a - y.b) + (y.a - x.b);
Run Code Online (Sandbox Code Playgroud)
谁能解释为什么c这里的值为0?
您只能访问联合的最后写入字段.此代码违反了此规范,因此会调用未定义的行为.
实质上,由于MyUnion.x和MyUnion.y共享相同的内存,您可以用以下代码替换代码:
int x, y;
x = 5;
y = 2;
y = 3;
x = 1;
int c = (x - y) + (y - x);
Run Code Online (Sandbox Code Playgroud)
这简化为c = (1 - 3) + (3 - 1),-2 + 2或者0.
请注意,这只是基于观察,这是编译器通常看起来如何实现联合,并且它解释了观察到的行为.它仍然未定义,你应该小心这样的代码.
这是未定义的行为.如果您上次写信x.a,则不允许阅读x.b,反之亦然.
实际上,您可以像这样重新排列表达式:
int c = (x.a - x.b) + (y.a - y.b);
Run Code Online (Sandbox Code Playgroud)
由于在实践中x.a和x.b共享相同的存储位置(所以做y.a和y.b),这两个操作数+始终为零.