Skip to content

Case 47: Inline Function Moved to Outlined

Field Value
Verdict 🟢 COMPATIBLE
Category Addition (Compatible)
Platforms Linux, macOS, Windows
Flags
Detected ChangeKinds
Source files browse on GitHub

Category: Compatible | Verdict: 🟢 COMPATIBLE

What does NOT break

In v1, Calculator::add() is defined inline in the header — no exported symbol. In v2, it is moved out-of-line — the symbol is now exported from the .so.

Consumers compiled against v1 already have the inlined body baked into their binary. Consumers compiled against v2 will call the exported symbol. Both work correctly. No existing binary breaks — this is a FUNC_ADDED (compatible extension).

Why abidiff sees it as compatible

abidiff reports Function_Symbol_Added and exits 4 (change detected), but the change kind is additive. abicheck classifies as COMPATIBLE (FUNC_ADDED).

Code diff

v1.hpp v2.hpp
inline int add(int a, int b) { return a + b; } int add(int a, int b); — definition in v2.cpp
No exported symbol for add Symbol _ZN10Calculator3addEii now exported

Real Failure Demo

Severity: ✅ BASELINE — no failure

g++ -shared -fPIC -g v1.cpp -o libv1.so
g++ -shared -fPIC -g v2.cpp -o libv2.so

abidw --out-file v1.abi libv1.so
abidw --out-file v2.abi libv2.so
abidiff v1.abi v2.abi
echo "exit: $?"   # → 4 (FUNC_ADDED — change detected, but compatible)
nm -D libv2.so | grep add   # → T _ZN10Calculator3addEii (now exported)

Reproduce manually

g++ -shared -fPIC -g v1.cpp -o libv1.so
g++ -shared -fPIC -g v2.cpp -o libv2.so
abidw --headers-dir . --out-file v1.abi libv1.so
abidw --headers-dir . --out-file v2.abi libv2.so
abidiff v1.abi v2.abi

Why this is still a risk

While ABI-compatible, moving inline→outlined is a source-level change: any consumer that relied on the inlined body being optimized away (e.g. in constexpr contexts or LTO-heavy builds) may see different behavior. Document the change.


Source files

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