After the short series on reflection in C++26, we are now talking about contracts. It allows you to specify preconditions, postconditions and invariants for functions.
Advertisement
Rainer Grimm has been working as a software architect, team and training manager for many years. He enjoys writing articles on the programming languages ​​C++, Python, and Haskell, but also frequently speaks at expert conferences. On his blog Modern C++ he discusses his passion C++ in depth.

Contracts were already considered part of C++20, but were removed at the standards meeting in Cologne. Herb Sutter said Sutter’s Mill What it says about it: “Contracts are the most impressive feature of C++20 so far, and possibly the most impressive feature we’ve added to C++ since C++11.” With C++26 we will probably achieve this.
This article is based on the proposal P2961R2,
What is a contract?
A contract specifies interfaces to software components in a precise and verifiable manner. These software components are functions and methods that must satisfy preconditions, postconditions, and invariants. Here are the definitions:
- One to bet: a predicate that must apply when entering a function,
- One postcondition: a predicate that must apply when exiting the function,
- One to emphasize: a predicate that is said to hold its point in a calculation.
Preconditions and postconditions are placed outside the function definition, but invariants are placed inside the function definition. A predicate is an expression that returns a Boolean value.
Before I show you the first example, I’d like to write a little about the goals of contract design.
design goals
The following design goals are defined in English:
- The syntax should fit naturally into existing C++. The intent should be intuitive without creating any confusion for users unfamiliar with contract checking.
- A contract check must not be identical to an attribute, lambda, or any other pre-existing C++ construct. It should sit in its own, instantly recognizable design space.
- The syntax should feel beautiful and light. In this, more tokens and characters should not be used than necessary.
- To aid readability, the syntax should visually separate the different syntactic parts of a contract check. It should be possible to distinguish at a glance the name of the contract type, predicate, return value… (proposal P2961R2,
Now the first example is as follows:
int f(int i)
pre (i >= 0)
post (r: r > 0)
{
contract_assert (i >= 0);
return i+1;
}
pre
Or post
- Add an ante condition or post condition. A function can have any number of preconditions and postconditions. These can be mixed together as desired.
- There are context-dependent keywords, i.e. a keyword in some context, but an identifier outside this context.
- are located at the end of the function declaration.
post
There may be a return value. The identifier must appear before the predicate and followed by a colon.
contract_assert
- is a key word. Otherwise it may be indistinguishable from a function call.
assertion problem
The ideal keyword for assurance would be assert
But not contract_assert. assert
Used to express contract-like assertions in most programming languages. But C++ has a legacy problem.
#include
void f() {
int i = get_i();
assert(i >= 0); // identical syntax for contract assert and macro assert!
use_i(i);
}
assert
There is already a macro from header <cassert
,
Unfortunately, I cannot implement contracts because, to the best of my knowledge, no compiler supports its syntax.
What will happen next?
In my next article I will take a look at smaller features of the C++26 core language.
(rme)
