C 位移位:移位计数>;=字体宽度

C 位移位:移位计数>;=字体宽度,c,compilation,bit,compiler-warnings,bit-shift,C,Compilation,Bit,Compiler Warnings,Bit Shift,下面的代码在编译时抛出由第9行引起的警告: 警告:移位计数>=类型的宽度[-Wshift count overflow] 然而,第8行并没有抛出类似的警告,即使k==32(我相信)。我很好奇为什么会发生这种行为?我使用的是gcc编译器系统 #include <stdio.h> #include <stdlib.h> #include <string.h> int bit_shift(unsigned x, int i){ int k = i * 8

下面的代码在编译时抛出由第9行引起的警告:

警告:移位计数>=类型的宽度[-Wshift count overflow]

然而,第8行并没有抛出类似的警告,即使
k==32
(我相信)。我很好奇为什么会发生这种行为?我使用的是
gcc
编译器系统

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int bit_shift(unsigned x, int i){
    int k = i * 8;
    unsigned n = x << k; /* line 8 */
    unsigned m = x << 32; /* line 9 */
    return 0;
} 

int main(){
    bit_shift(0x12345678, 4);
    return 0;
}
#包括
#包括
#包括
整数位_移位(无符号x,整数i){
int k=i*8;

无符号n=xbit\u shift
k
的值取决于参数
i
。由于
bit\u shift
未声明
static
,因此可以从其他翻译单元调用它(读取:其他源文件)


因此,它无法在编译时确定此移位是否始终是一个问题。这与行
无符号m=x相反,
bit\u shift
k
的值取决于参数
i
。由于
bit\u shift
未声明
static
,因此它可能被调用d来自其他翻译单位(读取:其他源文件)


因此,它无法在编译时确定此移位是否始终是一个问题。这与行
无符号m=x相反,我认为第8行不抛出警告的原因是,将无符号int32>=32位左移位不是一种未定义的行为

C标准(N2716,6.5.7位移位运算符)规定:


E1的结果我认为第8行之所以没有抛出警告是因为左移一个无符号int32>=32位不是一种未定义的行为

C标准(N2716,6.5.7位移位运算符)规定:


E1的结果编译器不会通过只看到函数
bit\u shift
而知道
k>=32
。检查该函数的调用对于编译器来说可能是太多的工作。
x编译器不会通过只看到函数
bit\u shift
而知道
k>=32
。检查该函数的调用对于编译器来说可能是太多的工作或者编译器。
x感谢您的快速而精彩的解释!+1Re“因此在编译时无法确定此转换是否始终是一个问题”不知道某件事情总是有问题并不是不警告的理由。如果你知道至少有一次会有问题,你应该警告。这里的实际问题是编译器根本不认识问题;它在任何情况下都看不出有问题。@EricPostFischil:有趣的是,如果你写的
k=32;n=x@NateEldredge我用的是
gcc
,来确认(编辑问题是为了说明这一点)@NateEldredge这是一个很好的观察结果,它切入了我在这里想知道的核心。感谢你的快速而出色的解释!+1Re“因此在编译时无法确定此转换是否总是一个问题”不知道某件事情总是有问题并不是不警告的理由。如果你知道至少有一次会有问题,你应该警告。这里的实际问题是编译器根本不认识问题;它在任何情况下都看不出有问题。@EricPostFischil:有趣的是,如果你写的
k=32;n=x@NateEldredge我用的是
gcc
,来确认(编辑问题以说明这一点)@NateEldredge这是一个很好的观察结果,它切入了我在这里想知道的核心。