Case 03: Compatible Addition (New Export)¶
| Field | Value |
|---|---|
| Verdict | ๐ข COMPATIBLE |
| Category | Addition (Compatible) |
| Platforms | Linux, macOS, Windows |
| Flags | โ |
Detected ChangeKinds |
func_added |
| Source files | browse on GitHub |
Category: Symbol API | Verdict: ๐ข COMPATIBLE (exit 4)
What breaks¶
Nothing breaks in existing binaries โ they never referenced get_build(). The exit
code is still 4 because abidiff reports an ABI change (addition); it is
compatible by convention.
Why abidiff catches it¶
Reports 1 Added function: get_build() with exit 4. The absence of exit-bit 3
(value 8) means no breaking change.
Code diff¶
| v1.c | v2.c |
|---|---|
int get_version(void) { return 1; } |
int get_version(void) { return 1; } |
| (nothing) | int get_build(void) { return 42; } |
Real Failure Demo¶
Severity: INFORMATIONAL
Scenario: compile app against v1, swap in v2 .so without recompile.
# Build old library + app
gcc -shared -fPIC -g v1.c -o libfoo.so
gcc -g app.c -L. -lfoo -Wl,-rpath,. -o app
./app
# โ get_version() = 1
# Swap in new library (no recompile)
gcc -shared -fPIC -g v2.c -o libfoo.so
./app
# โ get_version() = 1 (same โ no breakage)
Why INFORMATIONAL: adding new exports is backward-compatible; existing binaries continue to work unchanged because they never referenced the new symbol.
Reproduce manually¶
gcc -shared -fPIC -g v1.c -o libfoo_v1.so
gcc -shared -fPIC -g v2.c -o libfoo_v2.so
abidw --out-file v1.xml libfoo_v1.so
abidw --out-file v2.xml libfoo_v2.so
abidiff v1.xml v2.xml
echo "exit: $?" # โ 4 (compatible addition)
How to fix¶
No fix needed โ this is the correct way to extend a library API. Just keep the SONAME unchanged for compatible additions and bump it on breaking changes.
Real-world example¶
glibc regularly adds new symbols (e.g., reallocarray, explicit_bzero) to minor
releases without bumping the SONAME, relying on this compatible-addition guarantee.
References¶
Source files¶
See also: Examples overview ยท All COMPATIBLE cases ยท Category: Addition (Compatible).