Skip to content

Case 125 โ€” Class Became final

Field Value
Verdict ๐ŸŸ  API_BREAK
Category API Break
Platforms Linux, macOS, Windows
Flags API break
Detected ChangeKinds type_became_final
Source files examples/case125_class_became_final/

Verdict: ๐ŸŸ  API_BREAK abicheck verdict: API_BREAK (with headers) / NO_CHANGE (object/ELF-only)

What changes

Version Declaration
v1 class Shape { ... };
v2 class Shape final { ... };

The class gains the final specifier. Its size, alignment, vtable and the mangled names of all its members are unchanged.

What breaks

Any consumer that derives from Shape (struct MyShape : public Shape) no longer compiles against v2 โ€” error: cannot derive from 'final' base. See app.cpp, which compiles against v1.h and fails against v2.h. Already-compiled binaries keep linking and running (the ABI is identical), so this is a pure source / API break, not a runtime ABI break.

Why this case exists โ€” a change no object inspection can detect

final is a C++ source-level specifier. It is not recorded in DWARF, in the symbol table, or anywhere in the object file โ€” the v1 and v2 .so files are ABI-identical. A tool that compares only binaries (or stripped/DWARF-only builds) cannot detect this change, and reports NO_CHANGE.

abicheck catches it only in header mode, where castxml parses the declaration and records the final class-key (ChangeKind type_became_final). This case demonstrates why source/header analysis โ€” not just object comparison โ€” is required for the full API picture. See Limitations โ†’ Source-only changes.

Reproduce manually

g++ -shared -fPIC -g v1.cpp -o libshape_v1.so
g++ -shared -fPIC -g v2.cpp -o libshape_v2.so

# Header mode โ€” detected:
abicheck compare libshape_v1.so libshape_v2.so \
    --old-header v1.h --new-header v2.h        # โ†’ API_BREAK (type_became_final)

# Object-only mode โ€” invisible:
abicheck compare libshape_v1.so libshape_v2.so # โ†’ NO_CHANGE

How to fix

Keep public base classes non-final, or document the inheritance contract. Adding final to a previously-extensible public class is a breaking API change and warrants a major version bump.


Source files

  • CMakeLists.txt
  • app.cpp
  • v1.cpp
  • v1.h
  • v2.cpp
  • v2.h

See also: Examples overview ยท All API_BREAK cases ยท Category: API Break.