C23 adds <stdckdint.h> for checked integer addition, subtraction, and multiplication. Each type-generic macro writes the result through a pointer and returns true when the mathematical result overflows. section 8.2
Checking addition without undefined behavior
unsigned result = 0; bool overflow = ckd_add(&result, UINT_MAX, UINT_MAX); printf("Overflow flag %s, result %x\n", (overflow ? "true" : "false"), result); The operation remains valid even when it overflows. The result contains the least significant bits of the mathematical result, while overflow reports that the value did not fit. section 8.2
The three checked arithmetic macros provide:
- ckd_add for addition, ckd_sub for subtraction, and ckd_mul for multiplication. section 8.2
- A destination pointer receiving the result and a Boolean overflow indicator. section 8.2
- Defined behavior for signed overflow cases that would make an ordinary expression invalid. section 8.2
Table 8.5 Functions for integer arithmetic. Most of these are type-generic macros, but some also have function interfaces for specific types. \(x\) and \(y\) denote the arguments, \(\overline{x}\) is a bitwise complement, \(w\) the width, and \(m\) the maximum value of the type.
| Function | Description | Remark |
abs, labs, llabs |
\(|x|\) | Type independent |
div, ldiv, lldiv |
\(x\)/\(y\) and \(x\)%\(y\) |
Type independent |
ckd_add |
\(x\)+\(y\) (LS bits) & overflow flag |
Target dependent |
ckd_mul |
\(x\)*\(y\) (LS bits) & overflow flag |
Target dependent |
ckd_sub |
\(x\)-\(y\) (LS bits) & overflow flag |
Target dependent |
stdc_bit_ceil |
\(2^{\lceil \log_2 x\rceil}\) | \(1\) if \(x \equiv 0\), \(0\) if \(x > m/2\) |
stdc_bit_floor |
\(2^{\lfloor \log_2 x\rfloor}\) | \(0\) if \(x \equiv 0\) |
stdc_bit_width |
\(1 + {\lfloor \log_2 x\rfloor}\) | \(0\) if \(x \equiv 0\) |
stdc_count_ones |
Number of \(1\)-bits in \(x\) | Type independent |
stdc_count_zeros |
Number of \(1\)-bits in \(\overline{x}\) | Type dependent |
stdc_has_single_bit |
There is 𝑁 with \(x \equiv 2^n\) | Type independent |
stdc_first_leading_one |
\(w - {\big\lfloor \log_2 x\big\rfloor}\) | \(0\) if \(x \equiv 0\) |
stdc_first_leading_zero |
\(w - {\big\lfloor \log_2 \overline{x}\big\rfloor}\) | \(0\) if \(x\) has all bits set |
stdc_leading_ones |
\(w - {\big\lfloor \log_2 \overline{x}\big\rfloor} - 1\) | \(w\) if \(x \equiv 0\) |
stdc_leading_zeros |
\(w - {\big\lfloor \log_2 x\big\rfloor} - 1\) | \(w\) if \(x \equiv 0\) |
stdc_first_trailing_one |
One plus LS \(1\)-bit in \(x\) | \(0\) if \(x \equiv 0\) |
stdc_first_trailing_zero |
One plus LS \(0\)-bit in \(x\) | \(0\) if \(x \equiv 0\) |
stdc_trailing_ones |
One plus LS \(0\)-bit in \(x\) | \(w\) if \(x \equiv 0\) |
stdc_trailing_zeros |
One plus LS \(1\)-bit in \(x\) | \(w\) if \(x \equiv 0\) |
Compare checked arithmetic with division, remainder, absolute-value operations, and related integer-library interfaces. section 8.2
