---
title: "Exploration of a more library-oriented approach to contracts"
document: P4324R0
date: 2026-08-14
audience: EWG
reply-to:
  - "Ville Voutilainen <ville.voutilainen@gmail.com>"
---

## Abstract

This paper supplies a design and implementation exploration for a more library-oriented approach to contracts.

The goal of the exploration is to look at an alternative model that is less compiler-dependent, more library-oriented, and by being especially the latter, more flexible and more user-extensible.

It may well have been the goal of P2900 and everything that came after it, including P3400, to keep the design(s) rigid and extensible only through committee action, with the goal of maintaining certain prime directives and principles.

This exploration quite intentionally chooses a completely different set of trade-offs, and provides user-extensibility, user-configurability and user-overrideability over all else.

This exploration is heavily based on ideas formulated in Bengt Gustafsson's paper [P3968](https://wg21.link/p3968), but also builds on various other papers such as [P4005](https://wg21.link/p4005) and [P4009](https://wg21.link/p4009), attempting to further refine those papers and address the review feedback given for them. The paper also builds on various analyses and ruminations performed on [P3400](https://wg21.link/p3400).

## The goal, elaborated

The goal of this approach is to provide a programmatic framework for expressing different needs for assertions, in different domains. There are various such needs that have already been communicated, such as being able to:

- turn off constification
- write contracts that do not translate predicate exceptions into contract violations, but pass such exceptions through
- write contracts that are always checked, and always enforced
- write contracts that, when enforced, terminate directly, without calling a violation handler (this is a library version of the quick_enforce semantic, that could have been used to add such a semantic in practice, if a framework like this had existed, and standardize it later)
- write contracts that, when enforced or observed, call the violation handler, but do not let exceptions escape the violation handler (this is a library version of the ruminated noexcept_enforce and noexcept_observe semantics)
- write contracts that define exactly what sort of termination is used (this is a library version of a possible implementation-defined mechanism for deciding what contract-termination does)

The framework also facilitates certain other desires that have been mentioned, such as being able to:

- write contracts that evaluate a predicate multiple times, to verify that the predicate doesn't have undesirable side effects
- write contracts that are enabled statically, but disabled (or otherwise semantic-controlled) at run-time

Some of these things are things that have been on the committee's agenda during the development of C++26 contracts. Some of them are possible implementation-defined mechanisms allowed by the standard. Some of them are facilities that may end up being on the committee's agenda to extend the C++26 contracts, or are already on that agenda.

This framework allows Just Doing them, in (3rd party) library code, which could later become standard library code.

## The approach

Let's first look at what the compiler does for a C++26 contract:

1. an assertion is parsed
2. and constified
3. an expression is created for the predicate
4. if the semantic is ignore, the assertion is ignored and the algorithm stops here
5. a call expression or function definition is transformed to
  1. evaluate the predicate
  2. if the result is false, either terminate, or invoke the violation handler, and after the violation handler returns, terminate or continue
  3. and the evaluation is done so that exceptions thrown by the predicate are translated into contract violations and the violation handler is called with such violations.

In this approach, it will be:

1. an assertion is parsed
2. based on the contract control object named (or the default) in the assertion, constification is or is not performed
3. an expression is created for the predicate
4. based on the contract control object named (or the default) in the assertion, a contract may be ignored, and the algorithm stops here
5. a function is created for the predicate
6. a call to the call operator of the contract control is emitted, passing in the function and an opaque handle representing the arguments of a function in case of a function contract assertion.

## The building blocks

To go straight to the point, the syntactic keying used here is similar to P3400: `void f(int x) pre<cco>(x >= 0);` and similarly for `post` and `contract_assert`. The `cco` in `pre<cco>` stands for Contract Control Object.

And that's what it is - an object that controls the semantics and the behavior of the contract.

Pay particular attention to "and the behavior". These control objects don't just compute semantics used by language-internal implementations of the standard semantics, they *implement* the semantics.

Right. Onto the actual building blocks.

We need

- a language<->library facility to allow the library-side control object to tell the language that an assertion is ignored. This causes there to be no checks emitted, as expected for the ignore semantic.
- a similar facility to allow the library-side control object to tell the language whether the predicate expression should be constified or not.
- a facility that allows the language to expose the predicate to the library-side control object as a callable.
- a facility that allows the language to expose the assertion metadata (assertion kind, semantic, comment, source location) to the library-side control object.

In addition, we need

- a way for the language to tell the library code what the implementation's configuration is for user-chosen contract-semantics
- a mechanism for the library code to invoke the violation handler with the arguments (semantic, assertion kind, detection mode, comment, source location).

### The concrete building blocks

We use a static-property information class:

> ```
>   class assertion_static_info {
>   public:
>     constexpr evaluation_semantic semantic() const noexcept;
>     constexpr assertion_check_side side() const noexcept;
>     constexpr bool is_virtual() const noexcept;
>     constexpr bool overrides_virtual() const noexcept;
>   };
> ```

The type of a contract control object has:

1. a `static constexpr bool is_ignored(assertion_static_info);`
2. a `static constexpr bool constify(assertion_static_info);`

These give us steps ii and iii.

For step v, the type of a contract control object also has:

1. a `constexpr void operator()(const assertion_context&);`

and assertion_context is

> ```
>   struct assertion_context {
>     constexpr const char* comment() const noexcept;
>     constexpr std::source_location location() const noexcept;
>     constexpr evaluation_semantic semantic() const noexcept;
>     constexpr assertion_kind kind() const noexcept;
>     constexpr bool check();
> 
>   private:
>     void* __args; // exposition-only
>     bool (*__check)(void*); // exposition-only
>   };
> ```

For invoking the violation handler, there is a function

> ```
>   void invoke_violation_handler(assertion_kind kind,
>                                        evaluation_semantic semantic,
>                                        detection_mode mode,
>                                        const char* comment,
>                                        std::source_location loc);
> ```

## Implementation experience

This approach has been implemented in a fork of GCC, at [https://github.com/villevoutilainen/gcc/tree/p4324](https://github.com/villevoutilainen/gcc/tree/p4324).

The compiler is available on godbolt, as "X86-64 gcc (P4324 contracts)".

### Examples

A pure-library version of quick_enforce; calls abort() on enforce, calls the violation handler on observe, ignores on ignore: [Library quick_enforce on godbolt](https://godbolt.org/z/1fc1hbhr5)

A pure-library version of noexcept_enforce/noexcept_observe: [Library noexcept_enforce/noexcept_observe on godbolt](https://godbolt.org/z/KTdbo5j9n)

Same example in the case where the handler throws: [Library noexcept_enforce/noexcept_observe on godbolt, with a handler throw](https://godbolt.org/z/bvMW3Gjv5)

An example of a contract that lets predicate exceptions through: [A throwing predicate, exception passed through, on godbolt](https://godbolt.org/z/cx9738TsG)

Same example, but we catch the exception and call the violation handler: [A throwing predicate, exception caught, on godbolt](https://godbolt.org/z/3no1veG3x)

An example of zero overhead (which can also be achieved with C++26 quick_enforce, but this shows it's attainable here too): [Zero-overhead example](https://godbolt.org/z/zK7ra7K1G)

A contract that is always checked and always enforced: [An always-on/enforced contract on godbolt](https://godbolt.org/z/xnTan19va)

A contract that is ignored at run-time based on an environment variable: [A run-time-ignored contract on godbolt](https://godbolt.org/z/a6d1hhd5G)

A contract that carries a custom diagnostic message: [A contract with a custom message on godbolt](https://godbolt.org/z/Pjdd59WEd)

The facility integrated to the standard library, implementing the hardened standard library: [Library hardening with P4324 on godbolt](https://godbolt.org/z/5szhM1T5K)
