Consider negating `INT_MIN` in C. Its positive counterpart is outside the signed integer range, so the negation overflows. Once execution reaches an operation with undefined behavior, the program has failed: no part of its subsequent execution can be relied upon. It might trap, behave strangely, or appear to work. A result that looks right on one platform or with one compiler setting provides no portability guarantee. section 5.7.5
for (unsigned i = 1; i; ++i) do_something(); for ( signed i = 1; i; ++i) do_something();
Compare the two incrementing loops. Unsigned arithmetic and signed arithmetic do not have the same overflow behavior; the signed loop can reach an overflowing increment. An apparently normal run is not evidence that the operation is safe. section 5.7.5
Failure has more than one route. A wrongdoing can directly cause it; program state can deteriorate over time; or individually valid actions can combine into an unfortunate incident. A livelock illustrates the last difficulty: activity continues, yet useful progress does not. How a failure manifests does not reliably identify its cause. section 15.0 section 15.4
TAKEAWAY: prevent failures where possible, and check for deterioration where prevention alone is insufficient.
- Test the preconditions of an operation that could fail, and take an alternative path when they do not hold. section 15.5
- Check potentially resource-exhausting C library calls for error returns; `errno` can also indicate an error. section 15.5
- Use careful design against failures arising from interacting parts of a program; they may offer few indicators to detect afterward. section 15.5 section 15.7
