devsda
devsda

Reputation: 4222

confusion in union concept

#include<stdio.h>

union node {
     int i;
     char c[2];
};

main() {

    union node n;
    n.c[0] = 0;
    n.c[1] = 2;
    printf("%d\n", n.i);
    return 0;
}

I think it gives 512 output becouse c[0] value stores in first byte and c[1] value stores in second byte, but gives 1965097472. Why ?. I compiled this program in codeblocks in windows.

Upvotes: 3

Views: 227

Answers (5)

Marco Leogrande
Marco Leogrande

Reputation: 8458

Undefined behavior is, well... undefined.

We can try to answer why a specific result was given (and the other answers do that by guessing compiler implementation details), but we cannot say why another result was not given. For all that we know, the compiler could have printed 0, formatted your hard drive, set your house on fire or transferred 100,000,000 USD to your bank account.

Upvotes: 1

Claudiu
Claudiu

Reputation: 229361

Your union allocates four bytes, starting off as:

[????] [????] [????] [????]

You set the least two significant bytes:

[????] [????] [0x02] [0x00]

You then print out all four bytes as an integer. You're not going to get 512, necessarily, because anything can be in those most significant two bytes. In this case, you had:

[0x75] [0x21] [0x02] [0x00]

Upvotes: 8

jxh
jxh

Reputation: 70402

Note that your int is likely to be at least 4 bytes (not 2, like it was in the good ol' days). To let the sizes match, change the type of i to uint16_t.

Even after this, the standard does not really permit setting one union member, and then accessing a different one in an attempt to reinterpret the bytes. However, you could get the same effect with a reinterpret_cast.

union node {
    uint16_t i;
    uint8_t c[2];
};

int main() {
    union node n;
    n.c[0] = 0;
    n.c[1] = 2;
    std::cout << *reinterpret_cast<uint16_t *>(&n) << std::endl;
    return 0;
}

Upvotes: 0

Arne
Arne

Reputation: 2146

The intis compiled as a 32 bit number, little endian. By setting the two lower bytes to 2 and 0 respectively and then reading the int you get 1965097472. If you look at the hexadecimal representation 7521 0200 you see your bytes again, and besides it is undefined behaviour and part of it depends on the memory architecture of the platform the program is running on.

Upvotes: 0

Luchian Grigore
Luchian Grigore

Reputation: 258608

Because undefined behavior. Accessing an union member that wasn't set does that, simple as that. It can do anything, print anything, and even crash.

Upvotes: 3

Related Questions