Examples & Case Encyclopedia¶
This catalog covers 105 cases demonstrating real-world ABI/API change scenarios for C/C++ shared libraries. Each case is a minimal compilable v1/v2 pair plus a consumer (app.c/app.cpp) that demonstrates the actual runtime effect.
Use this catalog to:
- Learn what kinds of changes break ABI vs. which are safe.
- See the runtime failure mode for each break (crash, wrong output, silent corruptionβ¦).
- Look up the mitigation pattern for a specific change.
- Cross-reference detected
ChangeKinds with concrete reproductions.
Ground truth. Expected verdicts and detected change kinds live in
examples/ground_truth.jsonand are the single source of truth β these pages are generated from that file plus per-caseREADME.mdfiles underexamples/.
Verdict distribution¶
| Verdict | Count | What it means |
|---|---|---|
| π΄ BREAKING | 76 | ABI breaks: existing consumers will fail at runtime. |
| π API_BREAK | 4 | Source-level / API-only breaks; recompilation fails or behavior shifts. |
| π‘ COMPATIBLE_WITH_RISK | 2 | Backward-compatible at the symbol level but with behavioral risk. |
| π’ COMPATIBLE | 20 | Backward-compatible changes (additions or quality-only). |
| β NO_CHANGE | 3 | Identical ABI/API β baseline control cases. |
How to read a case page¶
Each case page starts with a metadata table (verdict, category, platforms, detected change kinds) followed by:
- What changes / what breaks β the source diff between v1 and v2.
- Why abicheck (or abidiff/ABICC) catches it β detection mechanism.
- Real Failure Demo β exact shell commands that reproduce the runtime effect.
- How to fix β the mitigation pattern, where the README documents one.
- Real-world example β historical occurrences in widely-used libraries.
- References β links to relevant standards, manuals, and abicheck source.
Source files (v1.*, v2.*, app.*, CMakeLists.txt) are linked at the bottom of every page.
Browse by category¶
| Category | Cases | What it covers |
|---|---|---|
| Breaking | 76 | Listed in BREAKING_KINDS β runtime ABI break. |
| API Break | 4 | Listed in API_BREAK_KINDS β source/API-level break. |
| Risk | 2 | Listed in RISK_KINDS β symbol-compatible but behaviorally risky. |
| Addition (Compatible) | 10 | Listed in ADDITION_KINDS β backward-compatible additions. |
| Quality (Compatible) | 10 | Listed in QUALITY_KINDS β metadata/quality issues, not ABI breaks. |
| No Change | 3 | Identical ABI/API β sanity-check baselines. |
All cases¶
| Case | Title | Verdict | Category |
|---|---|---|---|
| case01_symbol_removal | Symbol Removal | π΄ BREAKING | Breaking |
| case02_param_type_change | Parameter Type Change | π΄ BREAKING | Breaking |
| case03_compat_addition | Compatible Addition (New Export) | π’ COMPATIBLE | Addition (Compatible) |
| case04_no_change | No Change | β NO_CHANGE | No Change |
| case05_soname | Missing SONAME | π’ COMPATIBLE | Quality (Compatible) |
| case06_visibility | Symbol Visibility Leak | π΄ BREAKING | Breaking |
| case07_struct_layout | Struct Layout Change | π΄ BREAKING | Breaking |
| case08_enum_value_change | Enum Value Change | π΄ BREAKING | Breaking |
| case09_cpp_vtable | C++ Vtable Change | π΄ BREAKING | Breaking |
| case105_concept_tightening | Concept Tightening (C++20) | π’ COMPATIBLE | Addition (Compatible) |
| case106_ctor_became_explicit | Conversion Operator Became explicit |
π API_BREAK | API Break |
| case107_task_scheduler_init_removed | task_scheduler_init Removed (oneTBB historical break) |
π΄ BREAKING | Breaking |
| case108_task_class_removed | task Class Removed (oneTBB historical break β vtable angle) |
π΄ BREAKING | Breaking |
| case109_flow_graph_policy_renames | flow::graph Policy Tag Renames | π΄ BREAKING | Breaking |
| case10_return_type | Return Type Change | π΄ BREAKING | Breaking |
| case110_concurrent_unordered_map_api_drift | concurrent_unordered_map API Drift | π΄ BREAKING | Breaking |
| case111_enumerable_thread_specific_lambda_ambiguity | enumerable_thread_specific Lambda-Init Ambiguity | π’ COMPATIBLE | Addition (Compatible) |
| case112_task_arena_attach_tag | task_arena::attach Tag Type Replaces Enum | π΄ BREAKING | Breaking |
| case113_internal_template_signature_changed | case113 β internal function-template signature leaks via public API (BREAKING) | π΄ BREAKING | Breaking |
| case114_cpo_kind_changed | case114 β CPO kind changed (BREAKING) | π΄ BREAKING | Breaking |
| case115_api_depends_on_consumer_env | case115 β public API depends on consumer build environment (RISK) | π’ COMPATIBLE | Quality (Compatible) |
| case116_cxx_standard_floor_raised | NO_CHANGE) | β NO_CHANGE | No Change |
| case117_experimental_graduated | case109 β experimental β stable graduation (compatible) | π’ COMPATIBLE | Addition (Compatible) |
| case118_experimental_removed_without_replacement | : removed without replacement (API break) | π΄ BREAKING | Breaking |
| case119_inline_namespace_version_bumped | case112 β inline namespace version bumped (BREAKING) | π΄ BREAKING | Breaking |
| case11_global_var_type | Global Variable Type Change | π΄ BREAKING | Breaking |
| case12_function_removed | Function Removed from Shared Library | π΄ BREAKING | Breaking |
| case13_symbol_versioning | Symbol Versioning Script | π’ COMPATIBLE | Quality (Compatible) |
| case14_cpp_class_size | C++ Class Size Change | π΄ BREAKING | Breaking |
| case15_noexcept_change | Case 15 β noexcept Changed |
π‘ COMPATIBLE_WITH_RISK | Risk |
| case16_inline_to_non_inline | Case 16 β Inline β Non-inline (ODR / Symbol Appearance) | π’ COMPATIBLE | Addition (Compatible) |
| case17_template_abi | Case 17 β Template Instantiation ABI Change | π΄ BREAKING | Breaking |
| case18_dependency_leak | Case 18 β Dependency ABI Leak | π΄ BREAKING | Breaking |
| case19_enum_member_removed | Case 19 β Enum Member Removed | π΄ BREAKING | Breaking |
| case20_enum_member_value_changed | Case 20 β Enum Member Value Changed | π΄ BREAKING | Breaking |
| case21_method_became_static | Case 21 β Method Became Static | π΄ BREAKING | Breaking |
| case22_method_const_changed | Case 22 β Method Const Qualifier Changed | π΄ BREAKING | Breaking |
| case23_pure_virtual_added | Case 23 β Virtual Method Became Pure Virtual | π΄ BREAKING | Breaking |
| case24_union_field_removed | Case 24 β Union Field Removed | π΄ BREAKING | Breaking |
| case25_enum_member_added | Case 25 β Enum Member Added | π’ COMPATIBLE | Addition (Compatible) |
| case26_union_field_added | Case 26 β Union Field Added | π΄ BREAKING | Breaking |
| case26b_union_field_added_compatible | Case 26b β Union Field Added (No Size Change) | π’ COMPATIBLE | Addition (Compatible) |
| case27_symbol_binding_weakened | Case 27 β Symbol Binding Weakened (GLOBAL β WEAK) | π’ COMPATIBLE | Quality (Compatible) |
| case28_typedef_opaque | Case 28 β Typedef and Opaque Type Changes | π΄ BREAKING | Breaking |
| case29_ifunc_transition | Case 29 β GNU IFUNC Transition | π’ COMPATIBLE | Quality (Compatible) |
| case30_field_qualifiers | Case 30 β Field Qualifier Changes (const, volatile) | π΄ BREAKING | Breaking |
| case31_enum_rename | Case 31 β Enum Member Rename | π API_BREAK | API Break |
| case32_param_defaults | Case 32 β Parameter Default Value Changes (C++) | β NO_CHANGE | No Change |
| case33_pointer_level | Case 33 -- Pointer Level Change | π΄ BREAKING | Breaking |
| case34_access_level | Case 34 β Access Level Changed | π API_BREAK | API Break |
| case35_field_rename | Case 35 -- Field Rename | π΄ BREAKING | Breaking |
| case36_anon_struct | Case 36 -- Anonymous Struct/Union Change | π΄ BREAKING | Breaking |
| case37_base_class | Case 37 -- Base Class Changes | π΄ BREAKING | Breaking |
| case38_virtual_methods | Virtual Method Changes | π΄ BREAKING | Breaking |
| case39_var_const | Variable Const Change | π΄ BREAKING | Breaking |
| case40_field_layout | Field Layout Changes | π΄ BREAKING | Breaking |
| case41_type_changes | Type-Level Changes | π΄ BREAKING | Breaking |
| case42_type_alignment_changed | Type Alignment Changed (standalone alignas) | π΄ BREAKING | Breaking |
| case43_base_class_member_added | Base Class Member Added | π΄ BREAKING | Breaking |
| case44_cyclic_type_member_added | Cyclic Type Member Added | π΄ BREAKING | Breaking |
| case45_multi_dim_array_change | Multi-Dimensional Array Element Type Change | π΄ BREAKING | Breaking |
| case46_pointer_chain_type_change | Pointer Chain Type Change | π΄ BREAKING | Breaking |
| case47_inline_to_outlined | Inline Function Moved to Outlined | π’ COMPATIBLE | Addition (Compatible) |
| case48_leaf_struct_through_pointer | Leaf Struct Change Propagated Through Pointer | π΄ BREAKING | Breaking |
| case49_executable_stack | Executable Stack (GNU_STACK RWX) | π’ COMPATIBLE | Quality (Compatible) |
| case50_soname_inconsistent | SONAME Inconsistent (Wrong Major Version) | π’ COMPATIBLE | Quality (Compatible) |
| case51_protected_visibility | Protected Visibility (DEFAULT to PROTECTED) | π’ COMPATIBLE | Quality (Compatible) |
| case52_rpath_leak | RPATH Leak (Hardcoded Build Directory) | π’ COMPATIBLE | Quality (Compatible) |
| case53_namespace_pollution | Namespace Pollution (Generic Symbol Names) | π΄ BREAKING | Breaking |
| case54_used_reserved_field | Used Reserved Field | π’ COMPATIBLE | Quality (Compatible) |
| case55_type_kind_changed | Type Kind Changed (struct β union) | π΄ BREAKING | Breaking |
| case56_struct_packing_changed | Struct Packing Changed (pragma pack) | π΄ BREAKING | Breaking |
| case57_enum_underlying_size_changed | Enum Underlying Size Changed | π΄ BREAKING | Breaking |
| case58_var_removed | Global Variable Removed | π΄ BREAKING | Breaking |
| case59_func_became_inline | Function Became Inline (outlined β inline) | π΄ BREAKING | Breaking |
| case60_base_class_position_changed | Base Class Position Changed (Multiple Inheritance Reorder) | π΄ BREAKING | Breaking |
| case61_var_added | Global Variable Added | π’ COMPATIBLE | Addition (Compatible) |
| case62_type_field_added_compatible | Type Field Added (Compatible β Opaque Struct) | π’ COMPATIBLE | Addition (Compatible) |
| case63_bitfield_changed | Bitfield Width Changed | π΄ BREAKING | Breaking |
| case64_calling_convention_changed | Calling Convention Changed | π΄ BREAKING | Breaking |
| case65_symbol_version_removed | Symbol Version Removed | π΄ BREAKING | Breaking |
| case66_language_linkage_changed | Language Linkage Changed (extern "C" removed) | π΄ BREAKING | Breaking |
| case67_tls_var_size_changed | TLS Variable Size Changed | π΄ BREAKING | Breaking |
| case68_virtual_method_added | Virtual Method Added to Non-Virtual Class | π΄ BREAKING | Breaking |
| case69_trivial_to_nontrivial | Trivially Copyable to Non-Trivial (Calling Convention Change) | π΄ BREAKING | Breaking |
| case70_flexible_array_member_changed | Flexible Array Member Element Type Changed | π΄ BREAKING | Breaking |
| case71_inline_namespace_moved | Inline Namespace Moved | π΄ BREAKING | Breaking |
| case72_covariant_return_changed | Covariant Return Type Changed | π΄ BREAKING | Breaking |
| case73_typedef_underlying_changed | Typedef Underlying Type Changed | π΄ BREAKING | Breaking |
| case74_detail_base_class_changed | Internal detail:: base class layout change leaks via public API |
π΄ BREAKING | Breaking |
| case75_detail_embedded_by_value | Internal detail:: impl struct embedded by value |
π΄ BREAKING | Breaking |
| case76_detail_pimpl_vtable_changed | Internal detail:: polymorphic base vtable change |
π΄ BREAKING | Breaking |
| case77_detail_templated_base_changed | Internal detail:: templated base class layout change |
π΄ BREAKING | Breaking |
| case79_missing_template_instantiation | Missing template instantiation in shipped binary | π΄ BREAKING | Breaking |
| case80_pimpl_shared_to_unique | Pimpl alias changed from shared_ptr to unique_ptr |
π΄ BREAKING | Breaking |
| case81_serialization_tag_reassigned | Serialization tag ID reassigned | π΄ BREAKING | Breaking |
| case82_sycl_overload_set_removed | SYCL overload set removed (DPC++ build withdrawn) | π΄ BREAKING | Breaking |
| case83_cpu_dispatch_isa_dropped | CPU-dispatch ISA family dropped | π‘ COMPATIBLE_WITH_RISK | Risk |
| case84_bundle_soname_skew | Multi-library bundle SONAME skew | π΄ BREAKING | Breaking |
| case86_tag_struct_renamed | Tag struct renamed (empty class re-mangling) | π΄ BREAKING | Breaking |
| case87_default_template_arg_changed | Default template argument changed | π΄ BREAKING | Breaking |
| case89_inline_accessor_renamed_pimpl_member | Inline accessor references renamed pimpl member | π΄ BREAKING | Breaking |
| case94_empty_tag_gained_state | Empty Tag Gained State | π΄ BREAKING | Breaking |
| case95_allocator_nested_typedef_removed | Allocator Nested-Typedef Removed | π΄ BREAKING | Breaking |
| case96_hidden_friend_removed | Hidden Friend Operator Removed | π API_BREAK | API Break |