Why (int *)0 + 1 Is Undefined Behavior in C/C++
The expression (int *)0 + 1 triggers undefined behavior in both C and C++. The ISO standards are explicit: pointer arithmetic is only valid when performed on a pointer that points into an allocated array object (a single object counts as a 1-element array). A null pointer doesn’t point into anything, so the rules simply don’t apply to it.
Why the Standard Forbids It
You’re only allowed to add or subtract an integer from a pointer if both the original pointer and the resulting pointer stay within the bounds of the same array object — or land exactly one element past the end.
Walking through (int *)0 + 1:
(int *)0evaluates to a null pointer.- A null pointer doesn’t refer to any valid object or array.
- With no array backing it, adding
1steps outside every safety guarantee the standard makes — hence, undefined behavior.
The Compiler’s Perspective
Compilers assume programmers follow the standard’s rules, and they lean on that assumption heavily when optimizing.
1. The size rule. When you add 1 to an int *, the compiler scales that 1 by sizeof(int) (commonly 4 bytes). It expects the result to land on the next element of a valid memory block — not just an arbitrary address.
2. Optimization exploits. Because arithmetic on a null pointer is UB, a compiler seeing p + 1 is entitled to assume p is not null — otherwise the arithmetic couldn’t be valid in the first place. In practice, this means a nearby if (p == NULL) check can be silently optimized away, since the compiler has already “proven” p can’t be null.
This is one of the more dangerous ways UB manifests: not as a crash, but as your own safety check quietly disappearing.
Hardware and Architecture Reasons
C was designed to run across wildly different hardware. On older segmented-memory architectures (like 16-bit x86), adding an offset to an invalid base address could wrap around physical memory boundaries — corrupting state or tripping hardware traps. To stay portable across every target CPU, the language just declared arithmetic on a null pointer invalid, full stop, rather than trying to define consistent behavior across incompatible memory models.
Takeaway
(int *)0 + 1 isn’t just “probably fine because it’s only an addition.” It removes ground the compiler relies on, which means it can produce surprising results far beyond the line where it appears — including deleted null checks elsewhere in the function. Treat null-pointer arithmetic the same as any other UB: don’t do it, even “just to compute an offset.”