I expected the following code involving constexpr to generate errors since all the shifts invoke undefined behavior: int main() { constexpr int x1 = 1 << 33 ; constexpr int x2 = 1 << -1 ; constexpr int x3 = -1 << 1 ; constexpr int x4 = 1 >> 33 ; constexpr int x5 = 1 >> -1 ; } but instead they generate warnings and all the variables are still considered constant expressions: main.cpp:3:34: warning: left shift count >= width of type [enabled by default] constexpr int x1 = 1 << 33 ; //Assuming 32-bit int ^ main.cpp:4:35: warning: left shift count is negative [enabled by default] constexpr int x2 = 1 << -1 ; ^ .... I built this using the following flags: -std=c++11 -Wall -Wextra -pedantic -fno-strict-aliasing -fwrapv and you can see it live here: http://coliru.stacked-crooked.com/a/95685bb86b5b81e7 while clang 3.5 will generate errors for all these cases, see it live here: http://coliru.stacked-crooked.com/a/0638d424b28ecd87 I brought this up on StackOverflow, since it was not clear to me this was a bug: http://stackoverflow.com/questions/21502017/is-the-compiler-allowed-leeway-in-what-it-considers-undefined-behavior-in-a-cons and although the consensus seems to be that this is strictly conforming standard behavior, a conversation I had offline suggests this behavior is surprising and probably not intended. Note that in all the other cases I have tested of undefined behavior in a constexpr gcc does generate an error for example: constexpr int x = std::numeric_limits<int>::max() + 1 ; generates the following error: main.cpp:6:61: error: overflow in constant expression [-fpermissive] constexpr int x = std::numeric_limits<int>::max() + 1 ; ^
GCC 4.9.3 still accepts the code, but GCC 5 and 6 reject it (see below). Test added in r236225. Resolving as Fixed. $ gcc -S -std=c++11 -w xx.cpp xx.cpp: In function ‘int main()’: xx.cpp:3:27: error: right operand of shift expression ‘(1 << 33)’ is >= than the precision of the left operand [-fpermissive] constexpr int x1 = 1 << 33 ; ~~^~~~~ xx.cpp:4:27: error: right operand of shift expression ‘(1 << -1)’ is negative [-fpermissive] constexpr int x2 = 1 << -1 ; ~~^~~~~ xx.cpp:5:28: error: left operand of shift expression ‘(-1 << 1)’ is negative [-fpermissive] constexpr int x3 = -1 << 1 ; ~~~^~~~ xx.cpp:6:27: error: right operand of shift expression ‘(1 >> 33)’ is >= than the precision of the left operand [-fpermissive] constexpr int x4 = 1 >> 33 ; ~~^~~~~ xx.cpp:7:27: error: right operand of shift expression ‘(1 >> -1)’ is negative [-fpermissive] constexpr int x5 = 1 >> -1 ; ~~^~~~~