iva*_*ult 22 c++ types bit-shift integer-promotion
考虑以下清单:
#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>);
Run Code Online (Sandbox Code Playgroud)
它可以与 GCC 和 Clang 很好地编译。我很困惑operator<<(uint8_t, uint32_t)
。为什么要签署结果?
Hol*_*olt 29
操作数应为整型或无作用域枚举类型,并执行整型提升。结果的类型是提升后的左操作数的类型。[...]
因此,对于unsigned char
和int
,左操作数从 1 提升unsigned char
为int
1(请参阅[conv.prom]),并且结果类型是提升后的左操作数之一,因此int
。
1至少在最常见的平台上(其中sizeof(char) < sizeof(int)
),否则它可能会被提升为unsigned int
if sizeof(char) == sizeof(int)
。
Eri*_*hil 14
对于<<
运算符来说,左操作数通过积分提升来提升。积分提升中有一些技术细节,但主要是: 类型比int
提升到的范围更窄int
。其他整数类型不变。
运算符的结果类型<<
是提升后其左操作数的类型。
在您的示例中,(signed char)1
和(unsigned char)1
比 更窄int
,因此它们被提升为int
,这相当于int32_t
您的 C++ 实现中的情况。31
是一个int
,所以它仍然存在int
。31u
是1u
,unsigned int
所以它们仍然存在unsigned int
。