Message: You are using memset() to initialize a union that also contains a member with a bigger size.
Category: Portability
Severity: Portability
Language: C/C++
A union is zero-initialized (= {0} or = {}), but its largest member isn't declared first - only the
first member is guaranteed to be fully written by that initializer, so the rest of the union's storage
(beyond the first member's size) may not actually end up zeroed.
An aggregate initializer for a union only initializes the first named member. If a smaller member is listed first, the initializer only guarantees that member's bytes are zeroed - the remaining bytes, which are only reachable through a later, larger member, are left with whatever was already in memory. Code that expects the whole union to be zero can then read uninitialized bytes through the larger member.
Declare the union's largest member first, so a {0}/{} initializer zeroes its entire storage.
Before:
void foo() {
union { char c; int i; } bad0 = {0}; // <- 'i' (the larger member) isn't first
}After:
void foo() {
union { int i; char c; } good0 = {0};
}- overlappingWriteUnion.md - a different union-related pitfall, about reading and writing two overlapping members in the same expression.