C++11 Standard, [expr.shift]/2
The value of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are zero-filled. IfE1
has an unsigned type, [...]. Otherwise, ifE1
has a signed type and non-negative value, and E1*2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
[emphasis mine]
This is affected slightly by DR1457 which makes shifting into the "sign-bit" defined behaviour:
Otherwise, if
E1
has a signed type and non-negative value, and E1*2E2 is representable in the corresponding unsigned type of the result type [...].
Anyway, in the OP, E1
is negative, so that's still Undefined Behaviour. As such, it is not allowed inside constant expressions:
[expr.const]/2 A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression [...]
- [...]
- a result that is not mathematically defined or not in the range of representable values for its type;
That point has changed (DR1313); in n3485 it says:
- an operation that would have undefined behavior [ Note: including, for example, signed integer over- flow (Clause 5), certain pointer arithmetic (5.7), division by zero (5.6), or certain shift operations (5.8) — end note ];
[class.static.data]/3
If a non-volatile
const static
data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression
Conclusion: shifting SCHAR_MIN
is not a constant expression, so you can't do that in the in-class initializer of a static data member.
Hint: always compile with -Wall -Wextra -pedantic
. Using no parameters IMO is a bad idea for g++ and compatible compilers. g++/clang++ per default use the gnu99
mode (see clang doc), which is an extension to C++98 AFAIK. Also, you'll miss many important warnings.