This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Open status.

### 3656. Inconsistent bit operations returning a count

Section: 26.5.5 [bit.pow.two] Status: Open Submitter: Nicolai Josuttis Opened: 2021-12-30 Last modified: 2022-02-23

Priority: 3

View all issues with Open 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.

Proposed resolution:

This wording is relative to N4901.

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

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

2. Modify 26.5.5 [bit.pow.two], as indicated:

   >     template<class T>
   >       constexpr Tint 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.