Adrian
Adrian

Reputation: 20068

Confusion with Unions in C

Simple question about this piece of code:

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

Can someone explain why the value of c is 0 here ?

Upvotes: 2

Views: 213

Answers (5)

vickirk
vickirk

Reputation: 4067

Because (1 - 3) + (3 - 1) = 0

There is only one 'value' in the union, they both use the same memory location, so the last assignment is what the value is.

Upvotes: 5

JohnD
JohnD

Reputation: 14757

Both x and y are storing one value, which is the last assigned value, so x holds 1 and y holds 3 (the value is held in both the "a" and "b" members because the storage for them "overlaps" (this is what a union is).

So the equation is (1 - 3) + (3 - 1) = 0

And yes, as the other folks have commented, the behavior is undefined (depending on your compiler you might get different answers), but this is why you are getting the value 0.

Upvotes: 3

Bartek Banachewicz
Bartek Banachewicz

Reputation: 39370

int c = (1 - 3) + (3 - 1);

When using union, you create space in memory for only one variable, thus replacing its value by last used call.

Upvotes: 3

unwind
unwind

Reputation: 399803

You can only access the last-written field of a union. This code violates that, and thus invokes undefined behavior.

In essence, since both MyUnion.x and MyUnion.y share the same memory, you can probably replace the code with:

int x, y;
x = 5;
y = 2;
y = 3;
x = 1;
int c = (x - y) + (y - x);

This simplifies down to c = (1 - 3) + (3 - 1), which is -2 + 2 or 0.

Note that this is simply based on the observation that this is how compilers typically seem to implement unions, and it explains the observed behavior. It's still undefined though, and you should be careful with code like this.

Upvotes: 6

NPE
NPE

Reputation: 500307

This is undefined behaviour. If you've last written to x.a, you're not allowed to read x.b and vice versa.

In practical terms, you can rearrange your expression like so:

int c = (x.a - x.b) + (y.a - y.b);

Since in practice x.a and x.b share the same memory location (and so do y.a and y.b), both operands to + are always zero.

Upvotes: 5

Related Questions