Two similar loops
Compare `for (unsigned i = 1; i; ++i)` with `for (signed i = 1; i; ++i)`. The unsigned loop can reach zero and stop. In the signed loop, incrementing past the representable range has undefined behavior; a compiler may therefore treat zero as unreachable and turn the loop into an infinite one. section 5.7.5
for (unsigned i = 1; i; ++i) do_something();
for ( signed i = 1; i; ++i) do_something();
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":3},{\"line\":0,\"ch\":6}],[{\"line\":1,\"ch\":3},{\"line\":1,\"ch\":6}],[{\"line\":0,\"ch\":8},{\"line\":0,\"ch\":16}],[{\"line\":0,\"ch\":3},{\"line\":0,\"ch\":6}],[{\"line\":1,\"ch\":3},{\"line\":1,\"ch\":6}],[{\"line\":0,\"ch\":10},{\"line\":0,\"ch\":16}],[{\"line\":1,\"ch\":10},{\"line\":1,\"ch\":16}]]"}
!@%STYLE%@!
The side-by-side loops isolate the change in integer type that changes what the compiler may assume. section 5.7.5
Undefined behavior means C imposes no requirements on what happens when an operation reaches an undefined state. No assumption about the rest of that execution is safe. The compiler may also reason as though the state will never be reached. TAKEAWAY: A program need not crash or look strange to have undefined behavior; apparent success on one platform or with one set of compiler options is no guarantee. section 5.7.5
Other operations require the same care:
- Dereferencing a null or indeterminate pointer with `*` has undefined behavior. A null pointer may crash promptly; an indeterminate pointer may instead modify an unintended object. section 11.1.1
- Arguments to `printf` or `fprintf` must correspond exactly to the format specifiers. A wrong modifier can also cause the value to be interpreted with the wrong type. section 8.3.4
- An aliasing trick that makes differently typed pointer parameters address the same object can make behavior undefined. Code must not rely on that trick to defeat the compiler's assumptions. section 12.3
- A thread writing a non-atomic object while another thread simultaneously reads or writes it makes the execution undefined. Use atomic objects to avoid such conflicting shared accesses. section 18.1
TAKEAWAY: Avoid undefined behavior at the operation that could cause it. Neither a familiar bit pattern, a plausible output, nor a successful test run establishes that an otherwise undefined execution is safe. section 5.7.5






