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