通常,C要求将二元运算符的操作数提升为更高级别操作数的类型。这可以被利用来避免使用详细的强制转换来填充代码,例如:
if (x-48U<10) ...
y = x+0ULL << 40;
等
但是,我发现,至少对于gcc,这种行为对于位移不起作用。即。
int x = 1;
unsigned long long y = x << 32ULL;
我希望右手操作数的类型能够将左手操作数提升为unsigned long long
,以便移位成功。但相反,gcc会打印一个警告:
warning: left shift count >= width of type
gcc是否已损坏,或标准是否对位移的类型提升规则有所例外?
答案 0 :(得分:29)
所谓的通常的算术转换适用于许多二元运算符,但不适用于所有二元运算符。例如,它们不适用于位移运算符,&amp;&amp;,||,逗号运算符和赋值运算符。这是位移运算符的规则:
6.5.7 ... 3语义......
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。
答案 1 :(得分:0)
问题实际上是促销只适用于您的平台定义为int
的任何内容。正如其他一些答案所述,位移运算符会将左操作数提升为int。但是,这里int
被定义为32位值。整数转换不会提升为long long
(64位)。