Search code examples
cinitializationunions

Which member of a global union variable that is not initialized explicitly will be initialized to 0 implicitly?


e.g.

union
{
    int n;
    void *p;
} u;

Is the initial value of u.n or that of u.p equal to 0?

It should be noted that a NULL pointer is not necessarily stored in all-zero bits. Therefore, even if u.n and u.p have the same size,

u.n == 0

doesn't guarantee

u.p == 0

and vice versa.

(Sorry for my poor English)


Solution

  • Since u is static then the first member will be initialized to zero, from the C99 draft standard section 6.7.8 Initialization paragraph 10:

    If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:

    — if it has pointer type, it is initialized to a null pointer;

    — if it has arithmetic type, it is initialized to (positive or unsigned) zero;

    — if it is an aggregate, every member is initialized (recursively) according to these rules;

    if it is a union, the first named member is initialized (recursively) according to these rules.

    since n is a arithmetic type it will be initialized to zero. The value of p is unspecified but in practice type punning is usually supported by the compiler for example the gcc manual points here for Type-punning and we can see under -fstrict-aliasing section is says:

    The practice of reading from a different union member than the one most recently written to (called “type-punning”) is common. Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type.

    It is also worth noting that you may be able to initialize any member of a union like so:

    union { int n; void *p; } u = { .p = NULL } ;
                                  ^^^^^^^^^^^^^
    

    I am not sure if all compilers support this though.