Search code examples
c++typesbit-shiftinteger-promotion

What is the result type of the bit shift operator?


Consider the following listing:

#include <type_traits>
#include <cstdint>

static_assert(std::is_same_v<decltype(31), int32_t>);
static_assert(std::is_same_v<decltype(31u), uint32_t>);

static_assert(std::is_same_v<decltype((signed char)1 << 1), int32_t>);
static_assert(std::is_same_v<decltype((signed char)1 << 1u), int32_t>);
static_assert(std::is_same_v<decltype((unsigned char)1 << 1), int32_t>);
// Signed result for unsigned char
static_assert(std::is_same_v<decltype((unsigned char)1 << 1u), int32_t>);
// But unsigned for uint32_t
static_assert(std::is_same_v<decltype(1u << 1u), uint32_t>);

It compiles fine with GCC and Clang. I am quite confused about operator<<(uint8_t, uint32_t). Why the result is signed?


Solution

  • Per [expr.shift]

    The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. [...]

    So for unsigned char and int, the left operand is promoted from unsigned char to int1 (see [conv.prom]), and the result type is the one of the promoted left operand, so int.


    1 At least on most common platforms (where sizeof(char) < sizeof(int)), otherwise it might get promoted to unsigned int if sizeof(char) == sizeof(int).