liveBook · Manning

Program failure

As explained in Modern C, Third Edition

Program failure is execution that can no longer be relied upon because the program has entered a state resulting from undefined behavior.

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

How Modern C, Third Edition covers it

How deep it goes
Distinguishes three routes to failure and gives prevention checks; excludes compilation, linkage, and startup failures.
Examples
Contrasts signed and unsigned incrementing loops and uses cyclic traffic detours to illustrate livelock.
What it assumes
Assumes familiarity with C integer operations and library calls; defines the reliability consequence of undefined behavior.
What you can do after
Practice/perform precondition checks and C library error checks, while designing to avoid failures with few detectable indicators.
How it connects
Connects undefined behavior and signed overflow to preconditions, resource exhaustion, and livelock.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.