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

nis*_*sah 8 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;
}
Run Code Online (Sandbox Code Playgroud)

Rya*_* Li 4

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

-W转换部分:

不要对像 abs ((int) x)and这样的显式转换发出警告ui = (unsigned) -1,或者如果像 in 那样的转换没有改变值abs (2.0)

由于2U是字面意思,gcc 知道:

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

总之,将有符号si与文字进行比较与与2U进行比较是相同的,即转换为不会改变结果。si2si == 2Usiunsigned

如果你与 2^32-1 (4294967295U) 进行比较,32位无符号整数中最大的,它不能在 中表示int,那么si即使它本身是负数也可能等于它si,这可能不是你想要的,所以使用-Wextra选项生成警告。