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

4611. bit_size_of overflow handling

Section: 21.4.12 [meta.reflection.layout] Status: New Submitter: Jay Ghiron Opened: 2026-08-05 Last modified: 2026-08-08

Priority: Not Prioritized

View other active issues in [meta.reflection.layout].

View all other issues in [meta.reflection.layout].

View all issues with New status.

Discussion:

Consider the following program, assuming the static_assert succeeds:

#include<meta>
#include<print>
#include<climits>
#include<cstdint>

static_assert(CHAR_BIT == 8 && sizeof(long) == 8 && SIZE_WIDTH == 64);

int main()
{
  std::println("{}", bit_size_of(^^long[288230376151711744]));
}

If the implementation supports an array of this size then it appears that this should output zero, since the multiplication that bit_size_of is described as doing (21.4.12 [meta.reflection.layout]) will wrap around to zero. I do not think this is the intent, however. Additionally if the type of 0ZU + CHAR_BIT is signed, then wraparound will not happen if the multiplication results in a value greater than std::numeric_limits<decltype(0ZU + CHAR_BIT)>::max().

The following proposed resolution is what GCC currently implements, Clang does not even allow constructing a type large enough to trigger this situation. In the extremely absurd situation CHAR_BIT > SIZE_MAX this would forbid any uses with an object type. Perhaps there should be additional wording to ensure that calls which result in an exception being thrown are still considered constant.

Proposed resolution:

This wording is relative to N5054.

  1. Modify 21.4.12 [meta.reflection.layout] as indicated:

    consteval size_t bit_size_of(info r);
    

    -?- Constant When:

    1. (?.1) — If r represents an unnamed bit-field or a non-static data member that is a bit-field with width W, when W is less than or equal to SIZE_MAX.

    2. (?.2) — Otherwise, if r represents a data member description (T, N, A, W, NUA, ANN) (11.4.1 [class.mem.general]) and W is not ⊥, when W is less than or equal to SIZE_MAX.

    3. (?.3) — Otherwise, when size_of(r) is less than or equal to SIZE_MAX / CHAR_BIT.

    -9- Returns:

    1. (9.1) — If r represents an unnamed bit-field or a non-static data member that is a bit-field with width W, then W.

    2. (9.2) — Otherwise, if r represents a data member description (T, N, A, W, NUA, ANN) (11.4.1 [class.mem.general]) and W is not ⊥, then W.

    3. (9.3) — Otherwise, CHAR_BIT * size_of(r).

    -10- Throws: meta::exception unless all of the following conditions are met:

    1. (10.1) — dealias(r) is a reflection of a type, object, value, variable of non-reference type, non-static data member, unnamed bit-field, direct base class relationship, or data member description.

    2. (10.2) — If dealias(r) represents a type, then is_complete_type(r) is true.