In the article on Standard Library hardening, we saw that many library requirements are expressed as "contracts." This post explores contracts in C++26 and how they can be applied to our own code.
The discussion starts with a simple example: a function that returns a value from a std::vector at a given index. Traditionally, the requirement that the index be valid is enforced with assert inside the function body. This approach has drawbacks. The requirement lives in the implementation, so someone reading only the declaration sees a vector and an index without the relationship between them. Assertions are also controlled only by NDEBUG, which removes the check entirely when defined.
C++26 contracts, introduced through P2900, move the requirement into the function signature with a pre(...) clause placed after the parameter list. This precondition states a condition expected to hold on entry to the function. The same requirement can also appear on the declaration, making it visible to anyone reading the API. Contracts offer several evaluation semantics, including ignoring a check, reporting a violation and continuing, or terminating the program, with the compiler implementation determining which are available and how they are selected.
Contracts also distinguish between what the caller must provide and what the function promises to return. Postconditions, introduced with post, express those promises without requiring manual checks before each return statement. This makes contracts useful for documenting APIs even when runtime checking is disabled.
The article concludes with a complete precondition example and covers further topics such as postconditions, the placement of contracts on declarations and definitions, compiler options, and details that can surprise developers.
Source: Hacker News · Summarized by HeadlinesBriefing