### 3656. Inconsistent bit operations returning a count

**Section:** 22.15.5 [bit.pow.two] **Status:** C++23
**Submitter:** Nicolai Josuttis **Opened:** 2021-12-30 **Last modified:** 2023-11-22 15:47:43 UTC

**Priority: **3

**View all issues with** C++23 status.

**Discussion:**

Among the bit operations returning a count, `bit_width()` is the only one not returning an `int`.

This has the following consequences:

std::uint64_t b64 = 1;
b64 = std::rotr(b64, 1);
int count1 = std::popcount(b64); // OK
int count2 = std::countl_zero(b64); // OK
int count3 = std::bit_width(b64); // OOPS

The last line may result in a warning such as:

Warning: conversion from `long long unsigned` to `int` may change value

You have to use a `static_cast` to avoid the warning.

Note that P0553R4 explicitly states the following design considerations,
which I would also assume to apply to the later added functions from P0556R3:

The counting operations return "`int`" quantities, consistent with the rule "use an `int` unless you
need something else". This choice does not reflect, in the type, the fact that counts are always non-negative.

*[2022-01-30; Reflector poll]*

Set priority to 3 after reflector poll.
Eight votes for P0, but request LEWG confirmation before setting it to
Tentatively Ready.

*[2022-02-22 LEWG telecon; Status changed: LEWG → Open]*

No objection to unanimous consent to send the proposed resolution for LWG3656 to LWG for C++23.
The changes in P1956 changed the functions to be more counting than mathematical.

*[2022-07-08; Reflector poll]*

Set status to Tentatively Ready after ten votes in favour during reflector poll.

*[2022-07-15; LWG telecon: move to Ready]*

*[2022-07-25 Approved at July 2022 virtual plenary. Status changed: Ready → WP.]*

**Proposed resolution:**

This wording is relative to N4901.

Modify 22.15.2 [bit.syn], header `<bit>` synopsis, as indicated:

[…]
template<class T>
constexpr ~~T~~int bit_width(T x) noexcept;
[…]

Modify 22.15.5 [bit.pow.two], as indicated:

template<class T>
constexpr ~~T~~int bit_width(T x) noexcept;

-11- *Constraints:* `T` is an unsigned integer type (6.8.2 [basic.fundamental]).

-12- *Returns:* If `x == 0`, `0`; otherwise one plus the base-2 logarithm of `x`,
with any fractional part discarded.