使用带有signed var和unsigned literal的== op时,GCC不会发出警告

时间:2010-12-03 15:45:38

标签: gcc casting compiler-warnings

为什么GCC仅警告下面的代码中的情况1和3而不是2?

我正在使用-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;
}

3 个答案:

答案 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^31s1 != 2U
  • 如果si > 0,那么(unsigned) si的值与si相同,因此(unsigned) si == 2U当且仅当si == 2

总之,将已签名的si与文字2U进行比较与将si2进行比较相同,即si == 2U的结果不会通过将si转换为unsigned来更改。

如果与2 ^ 32-1(4294967295U)进行比较,32位无符号整数中的最大值(int中无法表示),那么si即使si也等于{ {1}}本身是否定的,这可能不是您想要的,因此会使用-Wextra选项生成警告。

答案 1 :(得分:1)

可能是因为在该类型的有符号和无符号版本重叠的范围内,与常量的相等比较没有歧义。

如果我将其更改为

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

我收到警告

(实际上,在我收到您报告的警告之前,我必须添加-Wextra)

答案 2 :(得分:0)

克里斯谢谢你的回答。我认为这导致了原因。我最初的想法是U后缀会导致这个文字被提升为无符号类型,但我认为当数字大于INT_MAX_32时,它只被提升为无符号类型。 2147483647.