当将 == op 与有符号 var 和无符号文字一起使用时,GCC 不会发出警告

发布于 2024-10-06 08:49:32 字数 457 浏览 1 评论 0原文

为什么 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;
}

Why does GCC warn only for situations 1 and 3 and not 2 in the code below ?

I'm compiling with -Wall and -g flags.

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情绪 2024-10-13 08:49:33

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

-W转换部分:

不要对显式强制转换发出警告,例如
abs ((int) x)ui =(无符号)
-1
,或者如果值没有因转换而改变,如 abs (2.0)

由于 2U 是字面量,因此 gcc 知道:

  • if si < 0,则(无符号)si >= 2^31,因此 s1 != 2U
  • 如果 si > 0,则 (unsigned) sisi 具有相同的值,因此 (unsigned) si == 2U 当且仅如果si == 2

总之,比较带符号的 si 与文字 2U 与比较 si2 相同,即将 si 转换为 unsigned 不会改变 si == 2U 的结果。

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

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

-Wconversion section:

Do not warn for explicit casts like
abs ((int) x) and ui = (unsigned)
-1
, or if the value is not changed by the conversion like in abs (2.0).

Since 2U is literal, gcc know that:

  • if si < 0, then (unsigned) si >= 2^31, therefore s1 != 2U.
  • if si > 0, then (unsigned) si has the same value as si, therefore (unsigned) si == 2U if and only if si == 2.

In conclusion, comparing the signed si with literal 2U is the same as comparing si with 2, i.e., the result of si == 2U would not be changed by converting si to unsigned.

If you compare with 2^32-1 (4294967295U), the largest in 32-bit unsigned int, which is not representable in int, then si could be equal to it even if si itself is negative, this may not be what you wanted, so a warning is generated with -Wextra option.

眼泪淡了忧伤 2024-10-13 08:49:33

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

如果我将其更改为


如果(si==2147483648U){
printf(“xxxx”);
}

我收到警告

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

Possibly because there's no ambiguity in an equality comparison with constant in the range where signed and unsigned versions of the type overlap.

If I change it to


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

I get a warning

(Actually, I had to add -Wextra before I got the warnings you reported)

不疑不惑不回忆 2024-10-13 08:49:33

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

Chris thanks for your answer. I think it leads to the cause. My original thought was that the U suffix would cause this literal to be promoted to an unsigned type however I think that it is only promoted to an unsigned type when the number is greater than INT_MAX_32 that is > 2147483647.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文