Skip to content

Case 26b โ€” Union Field Added (No Size Change)

Field Value
Verdict ๐ŸŸข COMPATIBLE
Category Addition (Compatible)
Platforms Linux, macOS, Windows
Flags โ€”
Detected ChangeKinds โ€”
Source files browse on GitHub

Verdict: ๐ŸŸข COMPATIBLE

What changes

Version Definition
v1 union Value { long l; double d; };
v2 union Value { long l; double d; int i; };

Why this is NOT a binary ABI break

Adding int i does not change sizeof(union Value): - v1: sizeof = max(sizeof(long)=8, sizeof(double)=8) = 8 bytes - v2: sizeof = max(sizeof(long)=8, sizeof(double)=8, sizeof(int)=4) = 8 bytes

All existing fields remain at offset 0 with identical sizes and types. Old callers allocate exactly the right amount of memory for v2 as well. No struct embeddings or array strides are affected.

Contrast with case26

Case Field added sizeof change Verdict
case26 double d added to {int i; float f} 4 โ†’ 8 bytes BREAKING (TYPE_SIZE_CHANGED)
case26b int i added to {long l; double d} 8 โ†’ 8 bytes COMPATIBLE

Code diff

 union Value {
     long   l;
     double d;
+    int    i;   /* sizeof stays 8: smaller than double โ€” COMPATIBLE */
 };

Runtime Demo

# Build libs + app compiled against v1
make all

# Run with v1 lib โ€” baseline
./app_v1
# โ†’ after fill: v.l = 42
# โ†’ OK: union field added (no size change) is ABI-compatible

# Swap to v2 (old binary, new lib โ€” sizeof unchanged)
make test-compat
# โ†’ after fill: v.l = 42   โ† identical result
# โ†’ EXIT:0                  โ† app exits cleanly: COMPATIBLE

abicheck output

abicheck detects no TYPE_SIZE_CHANGED (sizeof stays 8 bytes). The added int i field appears as a new union member โ€” informational only. Verdict: COMPATIBLE.

References


Source files

See also: Examples overview ยท All COMPATIBLE cases ยท Category: Addition (Compatible).