Search code examples
c++unionstype-punning

Type punning - how does the compiler decide what type to use?


I was reading this question here about deciding endianness and the first answer baffled me somewhat.

The code used to decide big endianness is as follows:

int is_big_endian(void)
{
    union {
        uint32_t i;
        char c[4];
    } bint = {0x01020304};

    return bint.c[0] == 1; 
} 

My question is how does the compiler here decide what type to use for that array of hex digits? Because technically it fits equally well in both that uint32_t or that char[4].

Why not just store it in the char[4] and skip the union?

Is there some advantage of a union here that I don't see? I know this is called type-punning, but I fail to see its advantage here.


Solution

  • My question is how does the compiler here decide what type to use for that array of hex digits?

    As with arrays and aggregate classes, the first initialiser initialises the first member; in this case i. (Of course, unlike those things, it doesn't make sense to have more than one initialiser).

    Why not just store it in the char[4] and skip the union? Is there some advantage of a union here that I don't see?

    The purpose of this is to initialise the 4-byte integer, then use the char array to examine the individual bytes to determine the memory order. If the most significant byte (0x01) is stored in the first byte, then the system is "big-endian"; otherwise it's "little-endian" (or perhaps something stranger).