Inconsistent bit operations returning a count
Nicolai Josuttis

Created on 2021-12-30.00:00:00 last changed 3 months ago


Date: 2022-02-23.11:10:51

Proposed resolution:

This wording is relative to N4901.

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

    template<class T>
      constexpr Tint bit_width(T x) noexcept;
  2. Modify [bit.pow.two], as indicated:

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

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

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

Date: 2022-02-22.00:00:00

[ 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.

Date: 2022-01-15.00:00:00

[ 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.

Date: 2021-12-30.00:00:00

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.

Date User Action Args
2022-02-23 11:10:51adminsetmessages: + msg12381
2022-02-23 11:10:51adminsetstatus: lewg -> open
2022-01-30 17:05:36adminsetmessages: + msg12327
2022-01-30 17:05:36adminsetstatus: new -> lewg
2022-01-15 19:07:13adminsetmessages: + msg12262
2021-12-30 00:00:00admincreate