This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


2484. char8_t and char16_t in integral promotions

Section: 7.3.7  [conv.prom]     Status: CD6     Submitter: Richard Smith     Date: 2021-04-01

[Accepted as a DR at the October, 2021 meeting.]

According to 7.3.7 [conv.prom] paragraphs 1-2,

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (6.8.6 [conv.rank]) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

A prvalue of type char16_t, char32_t, or wchar_t (6.8.2 [basic.fundamental]) can be converted to a prvalue of the first of the following types that can represent all the values of its underlying type: int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int. If none of the types in that list can represent all the values of its underlying type, a prvalue of type char16_t, char32_t, or wchar_t can be converted to a prvalue of its underlying type.

Because of its omission from the list of excluded types (perhaps as an oversight when it was added), char8_t is handled in the first paragraph. However, char16_t falls into the second paragraph, even though it is guaranteed to be convertible to int or unsigned int. This seems inconsistent, so perhaps char8_t should be moved to the second paragraph or char16_t moved to the first?

Notes from the August, 2021 teleconference:

char8_t should be handled by the second paragraph by including it in all three lists of types in the two paragraphs.

Proposed resolution (August, 2021):

Change 7.3.7 [conv.prom] paragraphs 1 and 2 as follows:

A prvalue of an integer type other than bool, char8_t, char16_t, char32_t, or wchar_t whose integer conversion rank (6.8.6 [conv.rank]) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

A prvalue of type char8_t, char16_t, char32_t, or wchar_t (6.8.2 [basic.fundamental]) can be converted to a prvalue of the first of the following types that can represent all the values of its underlying type: int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int. If none of the types in that list can represent all the values of its underlying type, a prvalue of type char8_t, char16_t, char32_t, or wchar_t can be converted to a prvalue of its underlying type.