Title
Underlying `bool` type in `make_signed` and `make_unsigned`
Status
new
Section
[meta.trans.sign]
Submitter
Jan Schultke

Created on 2026-10-23.00:00:00 last changed 1 week ago

Messages

Date: 2026-10-31.14:41:59

Proposed resolution:

This wording is relative to N5054.

  1. Modify [meta.trans.sign] as indicated:

    Table 59 — Sign modifications [tab:meta.trans.sign]
    Template Comments
    template <class T>
    struct make_signed;
    If `T` is a (possibly cv-qualified) signed integer type ([basic.fundamental]) then the
    member typedef type denotes `T`; otherwise, if `T` is a (possibly
    cv-qualified) unsigned integer type then type denotes the
    corresponding signed integer type, with the same cv-qualifiers as `T`;
    otherwise, type denotes the signed integer type with smallest
    rank ([conv.rank]) for which `sizeof(T) == sizeof(type)`, with the same
    cv-qualifiers as `T`.
    Mandates: `T` is either an integral or enumeration type other than cv `bool`
    or an enumeration type whose underlying type is not `bool`.
    template <class T>
    struct make_unsigned;
    If `T` is a (possibly cv-qualified) unsigned integer type ([basic.fundamental]) then the
    member typedef type denotes `T`; otherwise, if `T` is a (possibly
    cv-qualified) signed integer type then type denotes the corresponding
    unsigned integer type, with the same cv-qualifiers as `T`; otherwise,
    type denotes the unsigned integer type with smallest rank ([conv.rank]) for
    which `sizeof(T) == sizeof(type)`, with the same cv-qualifiers as
    `T`.
    Mandates: `T` is either an integral or enumeration type other than cv `bool`
    or an enumeration type whose underlying type is not `bool`.
Date: 2026-10-23.00:00:00

The intent is for `make_signed` and `make_unsigned` to reject `bool`, which is enforced by their Mandates element. However, enumerations whose underlying type is `bool` are accepted (presumably by accident), with implementation divergence:

using SB = std::make_signed_t<bool>; // all reject
enum E : bool {};
using SE = std::make_signed_t<E>;    // libc++ rejects, others yield signed char
History
Date User Action Args
2026-10-31 14:30:53adminsetmessages: + msg16638
2026-10-23 00:00:00admincreate