liveBook · Manning

Precondition

As explained in Modern C, Third Edition

A platform precondition is a required property or capability of the execution environment that must hold for code to be valid or executable.

#if !__STDC_LIB_EXT1__
# error "This code needs bounds checking interface Annex K"
#endif

This guard stops compilation when the bounds-checking interface required by the code is unavailable. section 8.1.5

A precondition is something that must hold before code can be used correctly. A platform precondition concerns the execution environment rather than a particular function call. Portable C code should assume as little about that environment as possible; when an assumption is unavoidable, identify it explicitly. TAKEAWAY: A missing platform precondition must abort compilation. section 8.1.5

Choose a check according to when its condition can be evaluated:

  • Use #if and #error for preprocessor-checkable requirements. Conditions evaluate macros and integer literals; an unknown identifier evaluates to 0. Feature tests include defined, __has_include, __has_embed, and __has_c_attribute. section 8.1.5
  • Use static_assert for a condition known at compile time but not during preprocessing, such as a comparison of type sizes. Before C23, the keyword was _Static_assert. section 8.1.5
static_assert(sizeof(double) == sizeof(long double),
  "Extra precision needed for convergence.");

This assertion checks a type-size requirement after preprocessing while still guaranteeing a compile-time check. section 8.1.5

A function can also have preconditions on its arguments. For example, gcd2 requires its first argument to be no greater than its second and makes that requirement explicit with assert(a <= b). Its recursive call preserves the requirement. This is a run-time call condition, not a substitute for rejecting an unsupported platform during compilation. section 7.3 section 8.1.5

For operations that could fail, check preconditions and take an alternative path when they do not hold. Check error returns separately for operations that may exhaust resources: a precondition check cannot establish that such an operation succeeded. section 15.5

How Modern C, Third Edition covers it

How deep it goes
Works through compile-time guards and static assertions, then distinguishes argument checks from checks of operations that may exhaust resources.
Examples
Uses an Annex K #if/#error guard, a type-size static_assert, and an asserted argument ordering in a recursive greatest-common-divisor function.
What it assumes
Assumes familiarity with C functions and macros; defines how preprocessor conditionals treat unknown identifiers.
What you can do after
Apply precondition checks to reject unsupported platforms at compile time and make function-call requirements explicit.
How it connects
Connects preconditions to portability, preprocessor conditionals, static assertions, recursion, and error handling.

Also explained in

Compare how 8 books explain precondition →

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.