2010-12-03 35 views
8

为什么GCC只在下面的代码中警告情况1和3,而不是2?GCC在使用带有符号变量和无符号变量的== op时不会发出警告

我正在编译-Wall和-g标志。

int main() { 

    unsigned int ui = 4; 
    int si = 6; 

    if (si == ui) { // Warning comparison b/w signed and unsigned 
     printf("xxxx"); 
    } 

    if (si == 2U) { // No Warning --- WHY ??? 
     printf("xxxx"); 
    } 

    if (si > 2U) { // Warning comparison b/w signed and unsigned 
     printf("xxxx"); 
    } 

    return 0; 
} 

回答

4

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

-Wconversion部分:

不发出警告的显式转换像 abs ((int) x)ui = (unsigned) -1,或者如果该值不被转换像abs (2.0)改变。

由于2U是文字,GCC知道:

  • 如果si < 0,然后(unsigned) si >= 2^31,因此s1 != 2U
  • 如果si > 0,那么(unsigned) si具有与si相同的值,因此(unsigned) si == 2U当且仅当si == 2

最后,比较签署si与文字2U相同比较si2,即,si == 2U结果不会被通过转换siunsigned改变。

如果你有比较2^32-1(4294967295U),32位无符号整数,这是不是在int表示的最大的,然后si可以等于它,即使si本身是负的,这可能不是是你想要的,所以会产生一个警告,-Wextra选项。

1

可能是因为在类型的有符号和无符号版本重叠的范围内,常量的平等比较中不存在歧义。

如果我将其更改为

if (si == 2147483648U) { printf("xxxx"); }

我得到一个警告

(事实上,我不得不添加-Wextra之前,我给你报的警告)

0

克里斯感谢你的答案。我认为这导致了事业。我原来的想法是,U后缀会导致这种文字被提升为无符号类型,但我认为只有当数字大于INT_MAX_32> 2147483647时才会提升为无符号类型。

+0

确实是`提升'为无符号,但当它的值小于2^31 - 1时没有区别。 – 2010-12-03 16:42:19