Namespaces
Variants
Actions

Function contract specifiers (since C++26)

From cppreference.com
< cpp‎ | language‎ | functions
 
 
C++ language
General topics
 
 

Function contract specifiers (preconditions spelled with pre and postconditions spelled with post) are specifiers that may be applied to the declarator of a function or of a lambda expression to introduce a function contract assertion of the respective kind to the corresponding function.

They ensure the specified condition holds during execution, triggering a violation (e.g. termination) in debug builds if the condition evaluates to false or the evaluation exits via an exception, and can be ignored in release builds for performance.

[edit] Precondition

A precondition (pre) is a predicate that the caller must ensure holds before invoking a function or lambda, checked in debug builds to validate inputs or state.

[edit] Postcondition

A postcondition (post) is a predicate that the callee must ensure holds after a function or lambda completes, verified in debug builds to confirm output or state.

[edit] Syntax

pre attr (optional) ( expr ) (1)
post attr (optional) ( result-name (optional) predicate ) (2)
attr - any number of attributes
result-name - identifier :
identifier - name of a result binding of the associated function
predicate - boolean expression that should evaluate to true
1) Precondition
2) Postcondition

[edit] Keywords

pre, post

[edit] Notes

Feature-test macro Value Std Feature
__cpp_contracts 202502L (C++26) Contracts

[edit] Example

  • The precondition of function normalize requires caller to pass normalizable vector.
  • The postcondition ensures that the function normalize returns a normalized vector.
Run this code
#include <array>
#include <cmath>
#include <concepts>
#include <contracts>
#include <limits>
#include <print>
 
template <std::floating_point T>
constexpr auto is_normalizable(const std::array <T, 3>& vector) noexcept
{
 const auto& [x, y, z]{vector};
 const auto norm{std::hypot (x, y, z)};
 
 return std::isfinite (norm) && norm > T {0};
}
 
template <std::floating_point T>
constexpr auto is_normalized(const std::array <T, 3>& vector) noexcept
{
 const auto& [x, y, z]{vector};
 const auto norm{std::hypot (x, y, z)};
 constexpr auto tolerance{010 * std::numeric_limits <T>::epsilon()};
 
 if (!is_normalizable(norm)) [[unlikely]]
 return false;
 
 return std::abs(norm - T{1}) <= tolerance;
}
 
template <std::floating_point T>
constexpr auto normalize(std::array <T, 3> vector) noexcept -> std::array <T, 3>
 pre(is_normalizable(vector))
 post(vector: is_normalized(vector))
{
 auto& [x, y, z]{vector};
 const auto norm{std::hypot (x, y, z)};
 
 x /= norm, y /= norm, z /= norm;
 
 return vector;
}
 
int main()
{
 const auto v = normalize<float>({0.3, 0.4, 0.5});
 std::println ("{}", v);
 
 const auto w = normalize<float>({0, 0, 0}); // violates pre- and post- conditions
 std::println ("{}", w);
}

Possible output:

[0.4242641, 0.56568545, 0.70710677]
[-nan, -nan, -nan]

[edit] References

  • C++26 standard (ISO/IEC 14882:2026):
  • 9.(3+c ) Function contract specifiers [dcl.contract]

[edit] See also

Contract assertions (C++26) specifies properties that must hold at certain points during execution[edit]
contract_assert statement (C++26) verifies an internal condition during execution[edit]

AltStyle によって変換されたページ (->オリジナル) /