本网站上的几个问题揭示了混合有符号和无符号类型时的缺陷,大多数编译器似乎都很好地生成了这种类型的警告。但是,GCC在将有符号常量赋值给无符号类型时似乎并不在意!请考虑以下程序:
/* foo.c */
#include <stdio.h>
int main(void)
{
unsigned int x=20, y=-30;
if (x > y) {
printf("%d > %d\n", x, y);
} else {
printf("%d <= %d\n", x, y);
}
return 0;
}
使用GCC 4.2.1进行编译,如下所示在控制台上没有输出:
gcc -Werror -Wall -Wextra -pedantic foo.c -o foo
生成的可执行文件生成以下输出:
$ ./foo
20 <= -30
在将带符号值-30
分配给无符号整数变量y
时,是否有某些原因导致GCC不生成任何警告或错误消息?
答案 0 :(得分:21)
使用-Wconversion:
~/src> gcc -Wconversion -Werror -Wall -Wextra -pedantic -o signwarn signwarn.c
cc1: warnings being treated as errors
signwarn.c: In function 'main':
signwarn.c:5: error: negative integer implicitly converted to unsigned type
我想这里的事情是gcc实际上非常擅长生成警告,但默认情况下不会这样做(有时是意外的)。浏览可用的警告并选择一组产生您认为有用的选项是个好主意。或者只是所有这些,并抛光代码,直到它闪耀! :)
答案 1 :(得分:7)
将负值转换为无符号类型的功能是C语言的功能。因此,默认情况下不会发出警告。如果你愿意的话,你必须明确地要求它。
关于你的程序输出的内容......使用%d
的{{1}}格式说明符和一个超出类型printf
范围的无符号值会导致未定义的行为,这就是你真的在实验中观察到了。
答案 2 :(得分:2)
使用(无符号)-1是一种常用的方法来设置所有位,有时甚至引用C作为此(错误)功能的原因,即使是那些应该更了解的人 。它既不明显也不可移植 - 你想用来设置所有位的表达式是〜0。