Case 57: Enum Underlying Size Changed¶
| Field | Value |
|---|---|
| Verdict | 🔴 BREAKING |
| Category | Breaking |
| Platforms | Linux, macOS |
| Flags | ABI break, API break |
Detected ChangeKinds |
enum_underlying_size_changed |
| Source files | browse on GitHub |
Category: Type Layout | Verdict: BREAKING
What this case is about¶
v1 defines Color enum with values 0-2 (fits in int, 4 bytes on LP64).
v2 adds a sentinel value 0x100000000LL that exceeds INT_MAX, forcing the
compiler to use a 64-bit underlying type.
This changes sizeof(Color) from 4 to 8, which breaks any struct containing
the enum.
What breaks at binary level¶
- Enum size doubles: 4 → 8 bytes. All structs containing
Colorchange layout. - Struct
Pixelgrows:alphamoves from offset 4 to offset 8. - Function ABI changes:
Coloris now passed in a 64-bit register/slot. - Arrays break:
Color arr[N]has different stride.
What abicheck detects¶
ENUM_UNDERLYING_SIZE_CHANGED: Detected via DWARFDW_AT_byte_sizeon the enumeration type.TYPE_SIZE_CHANGED: Structs containing the enum also change size.
Overall verdict: BREAKING
How to reproduce¶
gcc -shared -fPIC -g bad.c -include bad.h -o libbad.so
gcc -shared -fPIC -g good.c -include good.h -o libgood.so
python3 -m abicheck.cli dump libbad.so -o /tmp/v1.json
python3 -m abicheck.cli dump libgood.so -o /tmp/v2.json
python3 -m abicheck.cli compare /tmp/v1.json /tmp/v2.json
# → BREAKING: ENUM_UNDERLYING_SIZE_CHANGED
Real-world examples¶
- Adding a large sentinel to a public enum is a common mistake in C libraries.
- C++11's
enum class Color : uint64_tmakes the underlying type explicit, but changing it between releases still breaks ABI.
References¶
Source files¶
See also: Examples overview · All BREAKING cases · Category: Breaking.