Three checks, three positions
C++26 adds pre(...) after a function parameter list for conditions that must hold on entry. It adds post(result: ...) for conditions that must hold after a normal return. Inside the function, contract_assert(...) records a condition at that point in the implementation.
The first declaration establishes the function contract. A later declaration or definition can repeat the same sequence or omit it. A later declaration cannot introduce a different sequence. Contracts belong to the function, but they are not part of its type.
int clamp_value(int value, const int low, const int high)
pre(low <= high)
post(result: result >= low && result <= high)
{
if (value < low) return low;
if (value > high) return high;
contract_assert(value >= low && value <= high);
return value;
}
The policy can change
The working draft defines four evaluation semantics. ignore performs no runtime check. observe calls the violation handler and can continue if the handler returns. enforce calls the handler and then terminates if the handler returns. quick-enforce terminates without calling the handler.
The implementation chooses the semantic. The standard does not give each ordinary assertion a portable source-level policy switch. This is why contract predicates cannot carry required behavior or side effects. The program must still work when a predicate is ignored.
The predicate names the rule. The build policy decides how that rule is checked.
Expected failure still needs code
A bad value from a form, file, socket, or command line is an expected application event. Handle it with ordinary control flow. Return an error, throw an exception, or ask for another value according to the program's design. Then call the contracted helper only after the input satisfies its entry rule.
An observed violation can continue into code whose precondition is false. An ignored assertion does not evaluate its predicate at all. Neither mode is an input-validation strategy.
GCC makes the policy visible
GCC documents C++26 contract support behind -fcontracts. Its -fcontract-evaluation-semantic option accepts ignored, observed, enforce, and quick_enforce. GCC also documents caller-side and definition-side check controls. Those are compiler controls, not portable C++ syntax.
The article that sparked today's Hacker News discussion reports GCC 16 as the current compiler path and gives a small Compiler Explorer example. This dispatch did not compile or run that example. Treat the command below as a test recipe that still needs your GCC version, build flags, and observed output.
g++ -std=c++26 -fcontracts \
-fcontract-evaluation-semantic=enforce example.cpp
Write the review receipt first
- Name the requirement and decide whether it belongs at entry, normal return, or inside the function.
- Keep user input and recoverable failures in ordinary control flow.
- Keep contract predicates free of required side effects.
- Record the compiler, version, flags, handler, and expected response.
- Exercise a passing case and a deliberate violation. Save the real output before calling the policy verified.
The bench below drafts that receipt. It explains the documented semantics. It does not compile C++ or prove a toolchain configuration.