假设我们有以下代码,旨在将a
的位向左移动i
,并将i
的{{1}} LSB替换为{{ 1}}个a
i
这按预期工作。现在,让我们考虑一下这样的情况,我们希望能够对不同类型的对进行。即,我们想将b
的位向左移动unsigned short a;
unsigned short b;
auto i = 4;
a = (a << i) | (b >> (16 - i));
并用a
的{{1}}个MSB替换i
的{{1}} LSB,除非现在我们不能保证i
和{{1} },只有它们未签名。让我们考虑a
的大小小于i
b
我担心“ overshifting” a
。但是,取决于何时将b
提升为a
,该值可能是也可能不是超调。考虑值为b
。如果类型转换发生在移位之后而不是发生在移位之后,则将导致未定义的行为。因此,我的问题是在这种情况下何时会进行类型转换?我想我可以将unsigned short a;
unsigned int b;
auto i = 4;
a = (a << i) | (b >> (32- i));
显式转换为较大的类型,但是如果可能的话,我想避免这种情况。
答案 0 :(得分:1)
以下是标准[expr.shift/1]中的相关报价:
[...]操作数应为整数或无范围枚举类型,并执行整数提升。结果的类型是提升后的左操作数的类型。 [...]
在您的情况下,这意味着{1>}将在升级之前被a
提升为int
(或unsigned int
)。
请注意,对于当前的32/64位编译器,提升的类型为int
,而不是unsigned int
。仅当unsigned int
不能代表int
的整个范围时,提升的类型为unsigned short
(例如,对于旧的16位编译器,其中sizeof(int)
为2的情况,这是正确的) ,和sizeof(short)==sizeof(int)
)。