Skip to content

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).