Alternative text for NB comment GB-78

Jens Gustedt (INRIA France)

JeanHeyd Meneide (


org: ISO/IEC JCT1/SC22/WG14 document: N3103
target: IS 9899:2023 version: 1
date: 2023-02-06 license: CC BY

It was found that the discussion about valid and invalid initializers for constepxr variables, that the text in 6.7.1 p14 (note 2) needed a better exposure of the mechanisms that are in place. Therefore we propose to replace that note by the following.

proposed text

Replace NOTE 2 in clause 6.7.1 p14 by the following

NOTE 2 The constraints for constexpr objects are intended to enforce checks for portability at translation time.

constexpr unsigned int minusOne = -1;      // constraint violation
constexpr unsigned int uint_max = -1U;     // ok
constexpr double onethird       = 1.0/3.0; // possible constraint violation
constexpr double onethirdtrunc  = (double)(1.0/3.0);  // ok
constexpr _Decimal32 small      = DEC64_TRUE_MIN * 0; // constraint violation

If a truncation of excess precision changes the value in the initializer of onethird, a constraint is violated and a diagnostic is required. In contrast to that, the explicit conversion in the initializer for onethirdtrunc ensures that the definition is valid. Similarly, the initializer of small has a quantum exponent that is larger than the largest possible quantum exponent for _Decimal32.

Equally, implementation-defined behavior related to the char type may cause constraint violations at translation time:

constexpr char string[]            = {   "\xFF", }; // ok
constexpr char8_t u8string[]       = { u8"\xFF", }; // ok
constexpr unsigned char ucstring[] = {   "\xFF", }; // possible constraint
                                                    // violation

In both the string and ucstring initializers, the initializer is a (brace-enclosed) string literal of type char. If the type char is capable of representing negative values and its width is 8, then the code above is equivalent to:

constexpr char string[]            = {  -1, 0, }; // ok
constexpr char8_t u8string[]       = { 255, 0, }; // ok
constexpr unsigned char ucstring[] = {  -1, 0, }; // constraint violation

The hexadecimal escape sequence results in a value of 255. For an initializer of type char, it is converted to a signed 8-bit integer, making a value of -1. A negative value does not fit within the range of values for unsigned char, and therefore the initialization of ucstring is a constraint violation under the previously stated implementation conditions. In the case where char is not capable of representing negative values, the original snippet is equivalent to the following and there is no constraint violation.

constexpr char string[]            = { 255, 0, }; // ok
constexpr char8_t u8string[]       = { 255, 0, }; // ok
constexpr unsigned char ucstring[] = { 255, 0, }; // ok

note to editor

Please watch out for paragraph numbers.