Stefan12
Stefan12

Reputation: 21

Union data type field behavior

I am having trouble figuring out how this piece of code works. Mainly, I am confused by how does x.br get the value of 516 after x.str.a and x.str.b get their values of 4 and 2, respectively. I am new to unions, so maybe there is something I am missing, but shouldn't there only be 1 active field in an union at any given time?

#include <stdio.h>
void f(short num, short* res) {
    if (num) {
        *res = *res * 10 + num % 10;
        f(num / 10, res);
    }
}
typedef union {
    short br;
    struct {
        char a, b;
    } str;
} un;
void main() {
    short res = 0; un x;
    x.str.a = 4;
    x.str.b = 2;
    f(x.br, &res);
    x.br = res;
    printf("%d %d %d\n", x.br, x.str.a, x.str.b);
}

I would be very thankful if somebody cleared this up for me, thank you!

Upvotes: 0

Views: 118

Answers (3)

bigwillydos
bigwillydos

Reputation: 1371

how does x.br get the value of 516 after x.str.a and x.str.b get their values of 4 and 2

Your union definition

typedef union {
    short br;
    struct {
        char a, b;
    } str;
} un;

Specifies that un.br share the same memory address as un.str. This is the whole point of a union. This means that when you modify the value of un.br that you are also modifying the values for un.str.a and un.str.b.

I am new to unions, so maybe there is something I am missing, but shouldn't there only be 1 active field in an union at any given time?

Not sure what you mean by "only be 1 active field", but the members of a union are all mapped to the same memory address so any time that you write a value to a union member it writes that value to the same memory address as the other members. If you want the members to be mapped to different memory addresses so that when you write the value of a member it only modifies the value of that specific member, then you should use a struct and not a union.

Upvotes: 1

SHG
SHG

Reputation: 2616

To add to @Deepstop answer, and to correct an important point about your understanding -

shouldn't there only be 1 active field in an union at any given time?

There's no such a thing as active field in unions. All the different fields are referring to the same exact piece of memory (except miss-aligned data.

You can look at the different fields as different ways to interpret the same data, i.e. you can read your union as two fields or 8 bits or one field of 16 bits. But both will always "work" at the same time.

Upvotes: 3

Deepstop
Deepstop

Reputation: 3817

OK short is likely a 16 bit integer. Char a, b are each 8 bit chars.

So you are using the same 16 bit memory location for both.

0000 0010 0000 0100 is the 16 bit representation of 516
0000 0010           is the 8 bit representation of 2
          0000 0100 is the 8 bit representation of 4

The CPU you are running this on is 'little-endian' so the low-order byte of a 16 bit integer comes first, which is the 2, and the high order byte, the 4, comes second.

So by writing 2 then 4 into consecutive bytes, and reading them back as a 16 bit integer, you get 516, which is 2 * 256 + 4. If you wrote 3 then 5, you'd get 3 * 256 + 5, which is 783.

The point is that union puts two data structures in exactly the same memory location.

Upvotes: 1

Related Questions