We know that operations that would cause undefined behavior are not core constant expressions(section 5.19 paragraph 2 from the draft C++ standard)
In the tests I have done both clang
and gcc
treat undefined behavior in a constexpr as an error but they are inconsistent in the case of left an right shift. For example, in all of these cases which are considered undefined behavior according to section 5.8
Shift operators paragraph 1 to 3:
constexpr int x1 = 1 << 33 ; //Assuming 32-bit int
constexpr int x2 = 1 << -1 ;
constexpr int x3 = -1 << 1 ;
constexpr int x4 = 1 >> 33 ; //Assuming 32-bit int
constexpr int x5 = 1 >> -1 ;
clang
will produce an error (see it live):
error: constexpr variable 'x1' must be initialized by a constant expression
constexpr int x1 = 1 << 33 ; //Assuming 32-bit int
^ ~~~~~~~
note: shift count 33 >= width of type 'int' (32 bits)
constexpr int x1 = 1 << 33 ; //Assuming 32-bit int
....
while gcc
will produce a warning but it will still consider each variable to be constant expression (see it live):
warning: left shift count >= width of type [enabled by default]
constexpr int x1 = 1 << 33 ; //Assuming 32-bit int
^
warning: left shift count is negative [enabled by default]
constexpr int x2 = 1 << -1 ;
...
This looks like a gcc
bug but I know a compiler can make stronger guarantees for behavior the standard says is undefined and it does look like gcc gives some stronger guarantees for shifts. This may end up being a bug but it makes me wonder if the compiler allowed that same leeway in the context of a constexpr
as well or does the compiler have to strictly adhere to what the standard says is undefined behavior here?
Update
As Alan mentions, it is indeed true that the diagnostic of an ill-formed program can be either an error or a warning but in this case gcc
does not seem to consider the program ill-formed. Unlike other instances such as in the case of overflow, gcc
does not complain about an invalid constexpr but warns about the shifts. So then it would seem that either it is a bug or gcc
does not consider these cases to be undefined and hence my question.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…