Case 119: Internal struct loses a field (non-public, scoped)¶
| Field | Value |
|---|---|
| Verdict | ✅ NO_CHANGE |
| Category | No Change |
| Platforms | Linux, macOS, Windows |
| Flags | — |
Detected ChangeKinds |
— |
| Source files | examples/case119_internal_struct_field_removed_scoped/ |
Category: Public-surface scoping (ADR-024) | Verdict: ✅ NO_CHANGE (exit 0, with --scope-public-headers)
What changes¶
struct InternalStats drops a field (int errors;). Removing a field is
normally an ABI break for that struct — but InternalStats is not on the
public ABI surface: no exported, header-declared public function reaches it.
The public API (Point, translate) is unchanged.
Why this is not a false positive¶
Downstream consumers only observe the public API. Since nothing public reaches
InternalStats, removing one of its fields cannot break a caller that uses only
translate()/Point. With ADR-024 public-surface scoping the finding is moved
to the filtered audit ledger (visible via --show-filtered) instead of being
reported, and the verdict is NO_CHANGE.
abicheck compare libfoo_v1.so libfoo_v2.so -H v1.h \
--scope-public-headers --show-filtered
# verdict: NO_CHANGE (exit 0); filtered: type_field_removed: InternalStats
Scoping never hides a leak: if InternalStats were reachable from a public
API, the reachability closure keeps it on the surface and the removal is
reported as breaking.
How to fix¶
N/A — confined to an internal type, this is the intended compatible outcome.
Source files¶
app.cv1.cv1.hv2.cv2.h
See also: Examples overview · All NO_CHANGE cases · Category: No Change.