Case 20 โ Enum Member Value Changed¶
| Field | Value |
|---|---|
| Verdict | ๐ด BREAKING |
| Category | Breaking |
| Platforms | Linux, macOS, Windows |
| Flags | ABI break, API break |
Detected ChangeKinds |
enum_member_value_changed |
| Source files | browse on GitHub |
Verdict: ๐ด BREAKING Verdict detail: ABI break (runtime value mismatch) + API break (enum value changed in header) abicheck verdict: BREAKING
What changes¶
| Version | Definition |
|---|---|
| v1 | enum ErrorCode { OK = 0, ERROR = 1 }; |
| v2 | enum ErrorCode { OK = 0, ERROR = 99 }; |
What breaks at binary level¶
Changing the numeric value of an enum member is a semantic ABI break. Existing
binaries were compiled with ERROR = 1 and will pass, store, and compare that value.
The new library interprets ERROR as 99 โ the same symbolic name now maps to a
different integer.
This is effectively a protocol rewrite without version negotiation. Components built against different versions will exchange the same integer and interpret it with opposite semantics.
Consumer impact¶
/* consumer compiled against v1 */
if (result == ERROR) { /* ERROR = 1 */ }
/* with v2 library, ERROR = 99 */
/* consumer checks for value 1, library returns 99 */
/* error condition is silently missed */
Mitigation¶
- Never reassign released enum numeric values.
- Append new constants instead of renumbering.
- Introduce explicit protocol versioning for cross-version communication.
Code diff¶
Real Failure Demo¶
Severity: CRITICAL
Scenario: app compiled with old header (ERROR=1) checks the return value. v2 library now returns 99 for ERROR โ check silently fails.
# Build old lib + app
gcc -shared -fPIC -g old/lib.c -Iold -o liberr.so
gcc -g app.c -Iold -L. -lerr -Wl,-rpath,. -o app
./app
# โ Error detected (correct)
# Swap in new lib (ERROR=99)
gcc -shared -fPIC -g new/lib.c -Inew -o liberr.so
./app
# โ No error? Got 99 - WRONG! (v2 changed ERROR to 99)
Why CRITICAL: Error conditions are silently missed. Code that checks if (r == ERROR)
never triggers with v2 โ the error goes undetected. Any protocol, file format, or
IPC using these integer values is broken across version boundaries.
Why runtime result may differ from verdict¶
Enum value changed: integer value differs, silent wrong behavior
References¶
Source files¶
See also: Examples overview ยท All BREAKING cases ยท Category: Breaking.