General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
Contract assertions allow the programmer to specify properties of the state of the programthat are expected to hold at certain points during execution.
Contents |
Contract assertions are introduced byfunction contract specifiers andcontract_assert
statements. Each contract assertion has apredicate , which is an expression of typebool.
An evaluation of a contract assertion uses one of the following evaluation semantics:
Evaluation semantic | Is a checking semantic | Is a terminating semantic |
---|---|---|
ignore | ||
observe | Yes | |
enforce | Yes | Yes |
quick-enforce | Yes | Yes |
It is implementation-defined which evaluation semantic is used for any given evaluationof a contract assertion. The evaluation semantics can differ for different evaluations of the samecontract assertion, including evaluations during constant evaluation.
If the “ignore” semantic is used, the evaluation of a contract assertion has no effect.
If a checking semantic is used, the evaluationE
of a contract assertion determines the value of the predicate. It is unspecified whether the predicate is evaluated. If any of the following conditions is satisfied, acontract violation occurs:
There is anobservable checkpointCP
that happens beforeE
such thatany other operationOP
that happens beforeA
also happens beforeCP
.
int num=0;void f() pre((num++,false)); f();// Increment of “num” might not occur, even if a checking semantic is used
If a contract violation occurs in a context that is manifestly constant-evaluated:
If a contract violation occurs in a context that is not manifestly constant-evaluated:
When the program iscontract-terminated , it is implementation-defined (depending oncontext) whether
Thecontract-violation handler of a program is a function named::handle_contract_violation:
void handle_contract_violation( std::contracts::contract_violation); | (since C++26) (optionally noexcept) | |
A definition of the contract-violation handler, called thedefault contract-violation handler , is provided by the implemenation (instead of a standard library header).
It is implementation-defined whether the contract-violation handler isreplaceable. If the contract-violation handler is not replaceable, a declaration of a replacement function for the contract-violation handler is ill-formed, no diagnostic required.
When the contract-violation handler returns normally:
There is anobservable checkpointCP
that happens after the contract-violation handler returns normally such that any other operationOP
that happens afterthe contract-violation handler returns also happens afterCP
.
If the contract violation occurred because the evaluation of the predicate exited via anexception and the evaluation semantic is “observe” or “enforce”, the contract-violation handler is invoked from within an active implicithandler for that exception.
When the contract-violation handler returns normally:
The current exception can be inspected or rethrown within the contract-violation handler usingstd::current_exception().
Toevaluate in sequence a listR
of contract assertions:
S
such that all following conditions are satisfied:R
are inS
.R
may be repeated an implementation-defined number of times withinS
.A
precedes another contract assertionB
inR
, then the first occurrence ofA
precedes the first occurrence ofB
inS
.S
such that, if a contract assertionA
precedes a contract assertionB
inS
, then the evaluation ofA
issequenced before the evaluation ofB
.void f(int i){ contract_assert(i>0);// #1 contract_assert(i<10);// #2// valid sequence of evaluations: #1 #2 (no repeat)// valid sequence of evaluations: #1 #1 #2 #2 (repeat in sequence)// valid sequence of evaluations: #1 #2 #1 #2 (repeat alternatively)// valid sequence of evaluations: #1 #2 #2 #1 (second occurences can switch order)// invalid sequence of evaluations: #2 #1 (first occurences cannot switch)}
The range and flexibility of available choices of evaluation semantics depends on the implementation, and need not allow all four evaluation semantics as possibilities.
Different evaluation semantics chosen for the same contract assertion in different translation units can result in violations of theone-definition rule when a contract assertion has side effects that alter the value produced by a constant expression:
constexprint f(int i){ contract_assert((++const_cast<int&>(i),true));return i;} inlinevoid g(){int a[f(1)];// size dependent on the evaluation semantic of contract_assert above}
If the value that would result from evaluating the predicate istrue, no contract violation occurs and control flow continues normally after the point of evaluation of the contract assertion.
If the evaluation of the predicate exits by means ofnon-local jumps or terminating the program, no contract violation occurs either.
It is recommended by the C++ standard that the default contract-violation handler should produce diagnostic output that suitably formats the most relevant contents of the argument (rate-limited for potentially repeated violations of observed contract assertions), and then return normally.
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_contracts | 202502L | (C++26) | Contracts |
C++26 feature | Paper(s) | GCC | Clang | MSVC | Apple Clang | EDG eccp | Intel C++ | Nvidia HPC C++ (ex PGI)* | Nvidia nvcc | Cray |
---|---|---|---|---|---|---|---|---|---|---|
Contracts (FTM)* | P2900R14 |
contract_assert statement(C++26) | verifies an internal condition during execution[edit] |
function contract specifiers(C++26) | specifies preconditions (pre) and postconditions (post)[edit] |