Document number: P4347R0
Audience: EWG


Ville Voutilainen
2026-08-14

How to decouple UB-checks from Contracts

Abstract

This paper explains how to decouple UB-checks from Contracts. Because multiple people have expressed a desire to look at that. Further, this paper explains how to do that without redefining Undefined Behavior. This paper focuses on how. This paper doesn't focus on why.

The approach

Let's dive right into it. The first thing is to remove the UB-redefining. Do not introduce "Unconstrained Behavior", do not make Undefined Behavior refer to it.

Then, introduce the notion of implementation-defined UB-checks. Specify that

Then, modify the cases where the language says that the behavior is undefined to state that

Is this different for programmers?

No. One can envision that an implementation that would want to implement both P2900 and P3100 would allow enabling them separately, or in combination.

That separate enabling can also enable this approach, performing exactly the same checks as P3100 performs in a mode where its checks are enabled.

That combination-enabling can enable P2900 and the same checks for this approach as P3100 would enable.

How contract checks are controlled, and which P2900 semantics are chosen, is completely implementation-defined. Which semantics are even supported is implementation-defined. Which P3100 checks are supported or enabled is implementation-defined.

From that, it's a relatively short distance to a specification that specifies the same practical end result in terms of implementation-defined behavior instead of attempting to reuse the P2900 functionality.

The implementation-defined behavior isn't tied to P2900. But it can be, if the implementation so chooses. It can choose something different, or something beyond. An implementation can choose that its runtime diagnostic means invoking the contract violation handler, and it can decide to provide exactly the P2900 selection of semantics. It can provide more.

With P2900 and P3100, an implementation can already provide a subset of either.

Example

If a deallocation function terminates by throwing an exception, then

Another example:

The behavior of evaluating an arithmetic expression is undefined ifIf the mathematical result of evaluating an arithmetic expression is neither then