使用gcc时出现了奇怪的警告行为和有符号/无符号比较问题

8

我有以下代码:

unsigned int a;
if (a > numeric_limits<int>::max())
   do_stuff();

在编译时,gcc会有以下提示:

警告: "signed" 和 "unsigned" 之间的比较

好的,我理解了。

但是,对于以下代码:

unsigned int a;
if (a > (numeric_limits<int>::max()))
   do_stuff();

警告不再出现了,我真的不知道为什么... 这种行为有任何逻辑原因吗?还是我做错了什么?!

1
尝试模拟这种行为。但是它显示警告。 - iammilind
do_stuff() 部分只包含抛出异常的代码。由于这是函数中唯一的行,因此没有周围的代码。但是,该函数在一个大型项目中使用。我尝试了 iammilind 提供的代码,但是警告没有出现。以下是我用来编译程序的 gcc 选项:-Wall -ansi -pedantic -Wno-long-long - malamioute
1
@malamioute 请创建一个完整的(=编译),最小化的示例,仍然展示这种行为(好的,两个示例,一个带有警告,一个没有),并发布它们。由于我们无法重现您的问题,这表明问题实际上在其他地方。 - Konrad Rudolph
1
我也在gcc 4.6上看到了这种情况。可能是一个bug,也可能是为了能够在没有转换的情况下消除警告而引入的?最好的做法可能是直接向gcc开发人员询问。(我也在4.5和4.7上看到了这个问题) - PlasmaHH
1
@KonradRudolph 我已经使用iammilind提供的最小代码(编译)(请参见链接)测试了这种行为。在那种情况下,警告不会出现。我使用的gcc版本是4.6。 - malamioute
显示剩余2条评论
3个回答

5

这是因为它是一个错误。请参见错误50012


0

我目前没有C++编译器来测试这个,但我认为这可能在没有任何警告的情况下工作:

unsigned int a;
if (a > numeric_limits<unsigned int>::max())
   do_stuff();

这肯定会产生一个警告(语句始终为假)! - UncleBens
要在没有警告的情况下获得相同的结果,需要使用 if (a > unsigned(numeric_limits<int>::max())) - UncleBens
我现在也明白了。a 不能大于 0xffffffff,所以 if (a > unsigned(numeric_limits<int>::max())) 是正确的,正如 @UncleBens 所指出的那样。 - npclaudiu

-1
答案在于gcc处理int和unsigned int的方式。 unsigned int和int都存储2字节的值。它们之间的区别在于unsigned int不支持负值。它只能存储0-65,535之间的值。 当GCC看到int和unsigned int之间的比较时,它会将int转换为正数。例如,如果int的值为-2,则会将其转换为2。但是,如果int前面有()运算符。GCC将其解释为正数(但仍然进行转换),并且不会发出警告。

在一般情况下,int 不是一个“2字节值”,也不是今天几乎所有使用的 C++ 编译器中的值。 - Pavel Minaev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接