Skip to content

Instantly share code, notes, and snippets.

@vladiant
Created July 19, 2025 12:57
Show Gist options
  • Save vladiant/60b71e8eb4bfceee7b31b02489c7260f to your computer and use it in GitHub Desktop.
Save vladiant/60b71e8eb4bfceee7b31b02489c7260f to your computer and use it in GitHub Desktop.
C++ contracts

Contracts

Main features

contract_assert replaces assert

  • Unlike assert, contract_assert is a proper keyword

Four build options: the evaluation semantics

  • ignore – do not check the assertion;
  • enforce — check the assertion; if the check fails, print a message and terminate (the default behaviour);
  • observe — check the assertion; if the check fails, print a message and continue;
  • quick-enforce — check the assertion; if the check fails, terminate immediately, without printing a message or doing anything else.

Customising behaviour: the contract-violation handler

  • handle_contract_violation
  • contract_violation

pre and post

T& operator[] (size_t index) 
  pre (index < size());  // a precondition assertion 
void clear() 
  post (empty());  // a postcondition assertion 

Online Compiler support

Links:

// https://godbolt.org/z/qEo1vGhqM
// Use -std=c++23 -fcontracts -stdlib=libc++
//
// Change the evaluation semantic using
// -fcontract-evaluation-semantic=<ignore|observe|enforce|quick_enforce>
//
// Change evaluation in the standard library using:
// -fcontract-group-evaluation-semantic=std=<...>@
//
#include <string_view>
#include <iostream>
#include <contracts>
int f(const int x)
pre(x != 0)
post(r : r != x) {
return x + 1;
}
void try_contract_groups() {
// Turn on all "mylib" assertions using.
// -fcontract-group-evaluation-semantic=mylib=enforce
// Disable the debug group with
// -fcontract-group-evaluation-semantic=mylib=enforce,mylib.debug=ignore
// Or change "mylib.other" to quick_enforce with
// -fcontract-group-evaluation-semantic=mylib.hardening=quick_enforce
//
// Currently the flag is -fcontract-group-evaluation-semantic=mylib=observe
contract_assert [[clang::contract_group("mylib")]] (true);
contract_assert [[clang::contract_group("mylib.debug")]] (false && "mylib.debug");
contract_assert [[clang::contract_group("mylib.other")]] (false && "mylib.other");
}
void stdlib_using_contracts() {
std::cerr << "stdlib_using_contracts is about to quick_enforce and trap!" << std::endl;
std::string_view sv;
(void)sv.back();
}
// Try overriding the violation handler
void handle_contract_violation(std::contracts::contract_violation const& violation) {
if (violation.semantic() == std::contracts::evaluation_semantic::observe) {
std::cerr << violation.location().function_name() << ":"
<< violation.location().line()
<< ": observing violation my way: "
<< violation.comment()
<< std::endl;
return;
}
std::contracts::invoke_default_contract_violation_handler(violation);
}
int main() {
int r = f(1);
try_contract_groups();
stdlib_using_contracts();
}
// https://godbolt.org/z/7rPxa7TP6
int f(const int x)
pre(x != 0)
post(r : r > x) {
contract_assert(x != -1);
return x + 1;
}
int main() {
f(1);
f(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment