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 violationIf 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
// violationIn 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 violationThe 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, }; // okPlease watch out for paragraph numbers.