5.1.30 · D3C Programming

Worked examples — Undefined behavior — comprehensive list, why to avoid

3,098 words14 min readBack to topic

This page is the hands-on lab for the UB topic note. The parent listed the categories; here we run the actual experiments. We enumerate every kind of case UB can throw at you — each sign, each zero, each degenerate input, each limiting value — then work examples that hit every cell of that map. You guess first ("Forecast"), then we reason step by step, then we verify with real arithmetic.

Before line one: a quick vocabulary anchor so no symbol is unearned.


The scenario matrix

Every UB bug you meet in practice falls into one of the cells below. The job of the worked examples is to land on each cell at least once.

Cell Case class Degenerate / limiting input Example that hits it
A Signed overflow — positive side near INT_MAX Ex 1
B Signed overflow — the INT_MIN trap INT_MIN / -1 Ex 2
C Divide / modulo by zero denominator Ex 3
D Shift out of range shift or shift Ex 4
E Out-of-bounds — read past the end index length Ex 5
F Sequencing — modify twice, no order a[i] = i++ Ex 6
G Lifetime — dangling pointer pointer after scope ends Ex 7
H Varargs type mismatch (real-world) %d fed a double Ex 8
I Unsigned wrap is DEFINED (the control case) UINT_MAX + 1 Ex 9
J Exam twist — overflow check that vanishes x + 1 < x Ex 10

Prerequisite links live here so you can climb down whenever a cell confuses you: Integer Types and Overflow, Sequence Points and Operator Precedence, Pointers and Memory in C, malloc and free — Dynamic Memory, Compiler Optimizations and -O flags, Sanitizers — ASan and UBSan, Strict Aliasing Rule.

The figure below is the map — the number line of a signed int, with the danger points marked. Every arithmetic example refers back to it.

Figure — Undefined behavior — comprehensive list, why to avoid

Look at the two red cliffs at each end: stepping off either edge is UB. The mint region in the middle is the safe zone.


Cell A — Signed overflow, positive side


Cell B — The INT_MIN / -1 trap


Cell C — Divide / modulo by zero


Cell D — Shift out of range


Cell E — Out-of-bounds read


Cell F — Sequencing: modify twice, no order


Cell G — Lifetime: dangling pointer


Cell H — Varargs type mismatch (real-world)


Cell I — The control case: unsigned wrap is DEFINED


Cell J — Exam twist: the check that vanishes


Recall Which cell was each?

Ex 1 :: Cell A — positive signed overflow Ex 2 :: Cell B — INT_MIN / -1 Ex 3 :: Cell C — divide/modulo by zero Ex 4 :: Cell D — shift out of range Ex 5 :: Cell E — out-of-bounds read Ex 6 :: Cell F — sequencing double-modify Ex 7 :: Cell G — dangling pointer lifetime Ex 8 :: Cell H — varargs %d vs double Ex 9 :: Cell I — unsigned wrap (defined control case) Ex 10 :: Cell J — the vanishing overflow check