With a sufficient number of users of an API, it does not matter
what you promise in the contract: all observable behaviors of your
system will be depended on by somebody. — Hyrum's Law
In a compiler, the most common form of Hyrum's Law is dependence on
unspecified behavior — hash bucket order, the order of equal
elements after std::sort, padding offsets. The same framing
covers a few cases that are technically undefined behavior (use of an
invalidated iterator) or plain incidental properties (ABI struct layout,
ELF section offsets).
When the compiler itself harbors such a dependency, the symptom is
usually output that varies build-to-build: an unstable sort that lands
differently after the standard library changes, a hash map whose
iteration order shifts when the hash function does. Occasionally the
variation is run-to-run within a single build —
DenseMap<void *, X> keys with an ASLR-derived seed
reorder buckets each invocation. Either way, reproducible builds,
bisection, and bug reports all assume same input → same output, and a
stealth Hyrum dependency breaks that.
This post surveys some mechanisms that perturb the contract's blind
spots so dependencies cannot quietly form.
Read More