5.3.13 · D3Build Systems & Toolchain

Worked examples — Undefined Behavior Sanitizer (UBSan)

2,465 words11 min readBack to topic

Everything here rests on one number system: Two's Complement Representation for a 32-bit int, whose range is , i.e. . Keep those two edge numbers in your head — most of the traps live right at them.


The scenario matrix

Each cell is a distinct way a program can (or cannot) commit Undefined Behavior. We will hit every one.

Cell Case class The trap UBSan verdict?
A Signed add, same sign, past the edge INT_MAX + 1 ✅ overflow
B Signed add, opposite sign INT_MAX + (-1) ❌ always safe
C Signed negative edge overflow INT_MIN + (-1) ✅ overflow
D Unsigned overflow (the twist) UINT_MAX + 1u ❌ well-defined wrap
E Division degenerate INT_MIN / -1 ✅ overflow
F Division by zero x / 0 ✅ (separate check)
G Shift out of range n << 32, n << -1 ✅ bad shift
H Pointer misalignment / null ((S*)1)->a ✅ alignment
I Word problem (real bug) averaging two big sensor ints ✅ overflow
J Exam twist (optimizer + UB) null-check deleted at -O2 ✅ / silent

The single most important column is the last: for each cell you must know whether it is UB at all. Cells B and D look dangerous but are perfectly legal — knowing why is half the skill.


Case B vs A vs C — the sign logic, drawn

Before the examples, look at the picture that decides cells A, B, and C. The parent gave you the rule: only same-sign additions can overflow. Here is why, on a number line.

Figure — Undefined Behavior Sanitizer (UBSan)

Worked examples

Cell A — signed add, same sign, over the top

Cell B — signed add, opposite sign, always safe

Cell C — the negative cliff

Cell D — the unsigned twist (NOT UB)

Cell E — division that overflows

Cell F — division by zero (a different check)

Cell G — shift out of range, both directions

Cell H — misaligned / null pointer

Cell I — real-world word problem (the classic overflow bug)

Cell J — exam twist: the optimizer deletes your check


Putting the matrix together

Figure — Undefined Behavior Sanitizer (UBSan)

no, unsigned

opposite sign add

same sign or INT_MIN neg

shift or divide zero

bad pointer

signed op near an edge?

defined wrap mod 2 to the 32

always safe

UBSan reports overflow

UBSan reports constraint

UBSan reports alignment or null


Active recall

Recall Predict the verdict (cover the answers!)
  • INT_MAX + (-1) — UB? ::: No. Opposite signs move toward zero; result is in range.
  • UINT_MAX + 1u — UB? ::: No. Unsigned wraps to by definition; not caught by default.
  • INT_MIN / -1 — UB? ::: Yes. True value exceeds INT_MAX by 1.
  • 1 << 32 — UB and what does x86 do? ::: UB (shift width); x86 masks to 1<<0 = 1, silently wrong.
  • (lo+hi)/2 with lo=hi=2000000000 — UB? ::: Yes, the intermediate 4000000000 overflows int before the divide.
  • Why does the -O2 null-check disappear? ::: Deref before the check is UB, so p is assumed non-null; the if is deleted.

Back to Undefined Behavior Sanitizer (UBSan) · Hinglish: 5.3.13 Undefined Behavior Sanitizer (UBSan) (Hinglish)