2023-02-06
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.
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
Please watch out for paragraph numbers.