Renaming saturation arithmetic functions

Document number:
P4052R0
Date:
2026-03-13
Audience:
LEWG
Project:
ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21
Reply-to:
Jan Schultke <janschultke@gmail.com>
Corentin Jabot <corentin.jabot@gmail.com>
GitHub Issue:
wg21.link/P4052/github
Source:
github.com/eisenwave/cpp-proposals/blob/master/src/rename-sat.cow

Saturation arithmetic functions should be renamed. This paper resolves NB comment [FR-026-265].

Contents

1

Introduction

1.1

Arguments against sat

1.2

Broader design context

2

Proposal

3

Wording

4

References

1. Introduction

NB comment [FR-026-265] states the following:

The names add_sat, sub_sat, mul_sat etc are rather confusing and nondescript

Proposed change: Rename to saturating_add, saturating_sub, saturating_mul, saturating_div OR Rename to add_saturate / sub_saturate / mul_saturate / div_saturate.

[P0543R3] provides the following rationale for the status quo:

Naming

Considerations:

Options (only showing the operation "saturated addition"):

The last choice is taken.

1.1. Arguments against sat

The NB comment is right in the sense that to a novice, the abbreviation sat does not have obvious meaning. It can also be argued not to match the recommendation of the [LEWGDesignGuidelines]:

Avoid abbreviations except for common words: _ptr, std, etc. (apply common sense).

While conciseness is generally desirable in numeric context, it may have been given too much importance in [P0543R3]. Several arguments speak against the status quo:

1.2. Broader design context

The naming of saturation arithmetic functions is hugely important because it essentially sets the naming policy for all future arithmetic variations. For example, Rust supports a large amount of variations of multiplication:

Rust function Meaning C++ counterpart
saturating_mul Returns product clamped to numeric range of type C++26 std::mul_sat
overflowing_mul Returns product, as well as bool indicating overflow [P3161R4] std::mul_overflow,
C++26 and C23: ckd_mul,
GCC: __builtin_mul_overflow
widening_mul Returns low and high bits of product [P3161R4] std::mul_wide
wrapping_mul Wrapping multiplication (including for signed types) unsigned multiplication
checked_mul Returns Option<T> containing product,
or empty result on overflow
N/A

It is plausible that given time, some or all of these variations of multiplication could be available in C++. We thus need a sustainable naming scheme that can handle all such variations.

Also related is [P3642R4], which proposes std::clmul_wide as the widening variation of std::clmul. Note that the naming scheme here deliberately imitates that of std::mul_sat; it is not convergent evolution.

2. Proposal

The existing functions in [numeric.sat] should all be renamed to follow a saturating_op naming scheme, including std::saturate_cast. This should be done for the following reasons:

Furthermore, LEWG should commit to the Rust naming scheme for future proposals, such as [P3161R4] and [P3642R4], which propose std::mul_wide and std::clmul_wide, respectively.

3. Wording

The changes are relative to [N5032].

Bump the feature-test macro in [version.syn] as follows:

#define __cpp_lib_saturation_arithmetic 202311L 202603L // freestanding, also in <numeric>

Without bumping the feature test macro, __cpp_lib_saturation_arithmetic >= 202311L could be true, with std::saturating_add being ill-formed.

Change [numeric.ops.overview] as follows:

namespace std { […] // [numeric.sat], saturation arithmetic template<class T> constexpr T add_sat saturating_add(T x, T y) noexcept; template<class T> constexpr T sub_sat saturating_sub(T x, T y) noexcept; template<class T> constexpr T mul_sat saturating_mul(T x, T y) noexcept; template<class T> constexpr T div_sat saturating_div(T x, T y) noexcept; template<class T, class U> constexpr T saturate_cast saturating_cast(U x) noexcept; }

Rename the declarations in [numeric.sat] analogously.

4. References

[N5032] Thomas Köppe. Working Draft, Programming Languages — C++ 2025-12-15 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5032.pdf
[P3161R4] Tiago Freire. Unified integer overflow arithmetic 2026-03-12 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3161r4.html
[P3642R4] Jan Schulte. Carry-less product: std::clmul 2026-02-17 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3642r4.html
[FR-026-265] AFNOR. Confusing names add_sat, sub_sat, mul_sat 2025-10-03 https://github.com/cplusplus/nbballot/issues/840