Case 117: [[no_unique_address]] layout overlay (no new ChangeKind)¶
| Field | Value |
|---|---|
| Verdict | ๐ด BREAKING |
| Category | Breaking |
| Platforms | Linux |
| Flags | ABI break |
Detected ChangeKinds |
type_size_changed, type_field_offset_changed |
| Source files | examples/case117_no_unique_address/ |
Category: Binary ABI break / C++20 layout | Verdict: ๐ด BREAKING
What changed¶
v1 stores an empty stateless EmptyPolicy as an ordinary member of Widget,
so it occupies at least one byte and forces padding. v2 marks the same member
[[no_unique_address]], letting the compiler overlay it with the following
value member. Widget therefore shrinks and the offset of value moves.
Why there is no dedicated ChangeKind¶
This is the point of the case: [[no_unique_address]] does not need a special
detector. The overlay manifests as a plain layout change that abicheck already
catches with its existing structural kinds:
type_size_changed/struct_size_changedโsizeof(Widget)shranktype_field_offset_changed/struct_field_offset_changedโvaluemoved- possibly
type_alignment_changedโ depending on the members involved
A consumer compiled against the v1 layout reads value at the wrong offset
against v2. See docs/development/adr/0001-deferred-modern-cpp-abi.md for why
this (and not, say, C++20 modules) is in scope for the snapshot pipeline.
Files¶
v1.cpp/v2.cppโ the two library builds, with the ordinary vs[[no_unique_address]]member inlined (no header: the snapshot is taken from the compiled library's DWARF). This case is Linux-only โ the layout change is only visible via the ELF/DWARF path.app.cppโ minimal consumer stub
Source files¶
CMakeLists.txtapp.cppv1.cppv2.cpp
See also: Examples overview ยท All BREAKING cases ยท Category: Breaking.