Bitshift和整数推广?

通常,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是否被破坏,或者标准是否对比特提升的类型提升规则有所例外?

所谓的通常算术转换适用于许多二元运算符,但不适用于所有二元运算符。 例如,它们不适用于位移运算符,&&,||,逗号运算符和赋值运算符。 这是位移运算符的规则:

6.5.7 …… 3语义……
对每个操作数执行整数提升。 结果的类型是提升的左操作数的类型。 如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。

问题实际上是促销只适用于您的平台定义为int 。 正如其他一些答案所述,位移运算符会将左操作数提升为int。 但是,这里将int定义为32位值。 整数转换不会提升为long long (64位)。