为了将签名文字分配给无符号类型,为什么GCC不会产生警告?

本网站上的几个问题揭示了混合有符号和无符号类型时的缺陷,大多数编译器似乎都很好地生成了这种类型的警告。 但是,在为无符号类型指定有符号常量时,GCC似乎并不在意! 考虑以下程序:

/* foo.c */ #include  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不生成任何警告或错误消息?

使用-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实际上非常擅长生成警告,但默认情况下不会这样做(有时是意外的)。 浏览可用的警告并选择一组生成您认为有用的选项是一个好主意。 或者只是所有这些,并抛光代码,直到它闪耀! 🙂

将负值转换为无符号类型的能力是C语言的一个特性 。 因此,默认情况下不会发出警告。 如果你愿意的话,你必须明确地要求它。

至于你的程序输出什么…使用printf %d格式说明符和超出int类型范围的无符号值会导致未定义的行为,这是你在实验中真正观察到的。

使用(无符号)-1是一种常用的方法来设置所有位,有时甚至引用C作为这个(错误)特征的原因,即使是那些应该更了解的人。 它既不明显也不可移植 – 你想用来设置所有位的表达式是〜0。