Skip to content

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.json and are the single source of truth β€” these pages are generated from that file plus per-case README.md files under examples/.

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