Home > Mobile >  What is the result type of the bit shift operator?
What is the result type of the bit shift operator?

Time:01-05

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?

CodePudding user response:

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 int (see [conv.prom]), and the result type is the one of the left operand, so int.

CodePudding user response:

For the << operator, the left operand is promoted with the integral promotions. There are some technical details in the integral promotions, but largely they are: Types narrower than int are promoted to int. Other integer types are unchanged.

In your examples, (signed char)1 and (unsigned char)1 are narrower than int, so they are promoted to int, which is equivalent to int32_t in your C implementation. 31 is an int, so it remains int. 31u and 1u are unsigned int, so they remain unsigned int.

  •  Tags:  
  • c
  • Related