Case 26b โ Union Field Added (No Size Change)¶
| Field | Value |
|---|---|
| Verdict | ๐ข COMPATIBLE |
| Category | Addition (Compatible) |
| Platforms | Linux, macOS, Windows |
| Flags | โ |
Detected ChangeKinds |
โ |
| Source files | examples/case26b_union_field_added_compatible/ |
Verdict: ๐ข COMPATIBLE
What changes¶
| Version | Definition |
|---|---|
| v1 | union Value { long l; double d; }; |
| v2 | union Value { long l; double d; int i; }; |
Real Failure Demo¶
Severity: COMPATIBLE - NO FAILURE EXPECTED
This is intentionally a non-failure demo. The app is compiled against v1, then
run with v2 under the old SONAME. Because the added union field does not change
sizeof(union Value), the result is identical.
cmake -S examples -B /tmp/abicheck-examples-build -DCMAKE_BUILD_TYPE=Debug
cmake --build /tmp/abicheck-examples-build --target case27_union_field_added_compatible_app case27_union_field_added_compatible_v2
tmp=$(mktemp -d)
cp /tmp/abicheck-examples-build/case27_union_field_added_compatible/app_v1 "$tmp/"
cp /tmp/abicheck-examples-build/case27_union_field_added_compatible/libv2.so "$tmp/libv1.so"
(cd "$tmp" && LD_LIBRARY_PATH=. ./app_v1)
# after fill: v.l = 42
# OK: union field added (no size change) is ABI-compatible
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¶
CMakeLists.txtapp.c
See also: Examples overview ยท All COMPATIBLE cases ยท Category: Addition (Compatible).