2016-09-21 21 views
1

为什么这段代码生成一个警告:删除左移计数> =类型的警告宽度

niko: snippets $ cat leftshift.c 
#include <stdint.h> 
#include <stdio.h> 

int main(void) { 

    uint32_t var1; 
    uint32_t var2; 

    var1=55; 
    var2=var1 << (sizeof(uint32_t)-8); 

    printf("%d\n",var2); 
} 
niko: snippets $ gcc -g -Wl,--warn-common -ffunction-sections -fshort-enums -fdata-sections -Wall -Wextra -Wunreachable-code -Wmissing-prototypes -Wmissing-declarations -Wunused -Winline -Wstrict-prototypes -Wimplicit-function-declaration -Wformat -D_GNU_SOURCE -fshort-enums -std=c99 -c leftshift.c 
leftshift.c: In function ‘main’: 
leftshift.c:10:12: warning: left shift count >= width of type [-Wshift-count-overflow] 
    var2=var1 << (sizeof(uint32_t)-8); 
      ^
niko: snippets $ 

虽然相同的代码并不:

niko: snippets $ cat leftshift.c 
#include <stdint.h> 
#include <stdio.h> 

int main(void) { 

    uint32_t var1; 
    uint32_t var2; 

    var1=55; 
    var2=var1 << (32-8); 

    printf("%d\n",var2); 
} 
niko: snippets $ gcc -g -Wl,--warn-common -ffunction-sections -fshort-enums -fdata-sections -Wall -Wextra -Wunreachable-code -Wmissing-prototypes -Wmissing-declarations -Wunused -Winline -Wstrict-prototypes -Wimplicit-function-declaration -Wformat -D_GNU_SOURCE -fshort-enums -std=c99 -c leftshift.c 
niko: snippets $ 

是不是有什么毛病GCC?因为uint32_t的大小是32位或不是它?

回答

2

Sizeof以字节为单位返回大小。你应该试试这个:

printf("%d\n", sizeof(uint32_t)); 

你可能会发现,它是4,不是32.如果你想在位的大小,你可以乘以8:sizeof(uint32_t) * 8

+0

傻我。谢谢! – Nulik

+1

请注意,'%d'是'sizeof'返回的'size_t'的错误类型说明符。改为使用'%zu',或将参数强制转换为与类型说明符匹配的类型。 – user694733

+2

'sizeof(uint32_t)* CHAR_BIT'更加便携和自我记录。 OTOH'CHAR_BIT == 8'非常常见。 – chux

1

sizeof(uint32_t)是在你的系统中4,所以第一个代码得到正确的操作数为(4-8),这是一个负数,因此是警告。

在第二个代码中它是一个正数,所以没有警告。

+0

'sizeof(uint32_t)'是'size_t'类型,所以'sizeof(uint32_t)-8'产生一个非常大的无符号数。这就是为什么“左移计数**> = **宽度类型” – chux

+0

位运算符的右侧是加法表达式(c11的6.5.7)。它可以是负数,但如果它是负数,结果是未定义的。因此,整数升级将发生在sizeof(uint32_t)上,并且它将变成signed int并且结果将被签名为int。移位表达式的结果将是未定义的。 –

+0

如果'sizeof(size_t) = sizeof(int)',则结果是大的无符号整数。无论哪种方式,结果都不在右边的bitshift操作数的允许范围之内(0..31),行为是不确定的。 – user694733