为什么 Unsigned Int >= 0 的比较是“无意义的比较”?

发布于 2024-10-18 04:23:01 字数 425 浏览 8 评论 0原文

我收到警告:

Pe186“无符号整型与零进行毫无意义的比较”

Pe186当我尝试编译以下代码时,

for(clLoop = cpLoopStart; clLoop >= 0; clLoop--)                                  
{
    //Do something
}

:我不明白为什么。如果我正在寻找小于零的值,我可以理解,因为unsigned int永远不会是负数。但我在这里要寻找的是它是否等于为零,unsigned int 肯定可以。

如果在这个循环中我尝试预递减而不是后递减,我什至可以看到此错误,但情况又并非如此。

I got warning:

Pe186 "Pointless comparison of unsigned int with zero"

when I tried to compile the following code:

for(clLoop = cpLoopStart; clLoop >= 0; clLoop--)                                  
{
    //Do something
}

I don't understand why. I could understand, if I were looking for a value less than zero, since an unsigned int can never be negative. But all I am looking for here is if it is equal to zero, which an unsigned int certainly can be.

I could even see this error if in this loop I tried to pre-decrement instead of post-decrement, but again that is not the case.

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

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

发布评论

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

评论(10

枫以 2024-10-25 04:23:02

正如其他人已经指出的那样, unsigned int 始终 >= 0,即毫无意义的比较。 Mayank Jindal 为我发布了解决方案的起点。

要记录整个“修复”:请执行以下操作,这将按预期工作:

unsigned int cpLoopStart = 23U;
unsigned int clLoop = 0U;
for(clLoop = cpLoopStart; clLoop > 0U; clLoop--}
{
    //Do something
}

clLoop 将从 23 开始,在 1 结束,然后退出循环。我希望 clLoop 在循环内永远不会为 0。

我还喜欢为无符号类型值附加“U”,这使得在比较值和变量时也更加清晰。

As already stated by others unsigned int is always >= 0 i.e. pointless comparison. Mayank Jindal posted for me the starting point for a solution.

To document the "fix" as a whole: do the following instead, this works as intended:

unsigned int cpLoopStart = 23U;
unsigned int clLoop = 0U;
for(clLoop = cpLoopStart; clLoop > 0U; clLoop--}
{
    //Do something
}

clLoop will start at 23 and end at 1 then exits the loop. I hope it was intended that clLoop will never be 0 inside the loop.

I also prefer to append "U" for unsigned typed values, this makes is clearer also when comparing values and variables.

夜血缘 2024-10-25 04:23:01

您检查 unsigned int 是否大于或等于 (>=) 零。该表达式始终为真,因为无符号整数永远不会小于零。

编译器会尝试警告您即将编写无限循环。

You check whether the unsigned int is greater than or equal (>=) zero. This expression will always be true, because unsigned integers will never be less than zero.

The compiler tries to warn you that you are about to program an infinite loop.

月朦胧 2024-10-25 04:23:01

您正在检查无符号整数是否等于或大于 0。这始终是正确的。

You are checking if an unsigned int is equal or greater than 0. Which is always true.

非要怀念 2024-10-25 04:23:01

无符号整数即使在无限递减之后也永远不会低于 0(即 clLoop >= 0 始终为 true),这使得比较毫无意义。

An unsigned integer never falls below 0 even after decrementing infinitely (i.e. clLoop >= 0 will always be true), which makes the comparison pointless.

感性不性感 2024-10-25 04:23:01

我想你的意思是

for(clLoop = cpLoopStart; clLoop; clLoop--)                                  
{ //Do something
}

I think you meant to say

for(clLoop = cpLoopStart; clLoop; clLoop--)                                  
{ //Do something
}
囍笑 2024-10-25 04:23:01

clLoop >= 0 始终为真。无论是预递减还是后递减,无符号值至少为 0。递减 0 时,您将得到 UINT_MAX

编译器认为您可能并不打算永远循环(或者您使用了不同的构造,更明显的是永远循环),因此会出现警告。

clLoop >= 0 is always true. It doesn't matter whether you pre-decrement or post-decrement, an unsigned value is at least 0. When you decrement 0 you get UINT_MAX.

The compiler figures that you probably don't mean to loop forever (or you'd have used a different construct, that more obviously loops forever), hence the warning.

℉服软 2024-10-25 04:23:01

该警告抱怨您的 for 循环中断条件 clLoop >= 0。如果 clLoop 为负数,则循环将结束,但对于无符号 int 来说永远不会发生这种情况。

The warning complains about your for loop break condition clLoop >= 0. The loop will end if clLoop gets negative, but that will never happen for an unsigned int.

墨落画卷 2024-10-25 04:23:01

do{} while() 可以帮助您在 for 循环中使用无符号类型的变量而不会出现整数溢出:

// main.c
#include <stdio.h>

int main(void)
{

    int array[] = {1,2,3,4,5,6,7,8,9,10};
    unsigned int size = sizeof(array)/sizeof(int); // size == 10;

    unsigned int i = size;
    do
    {
        i--;
        printf("Index: %u, content: %d\n",i,array[i]);

    } while(i > 0);

    return 0;
}

并编译它:

gcc -std=c11 -Wall -Wextra -Wpedantic main.c

输出:

Index: 9, content: 10
Index: 8, content: 9
Index: 7, content: 8
Index: 6, content: 7
Index: 5, content: 6
Index: 4, content: 5
Index: 3, content: 4
Index: 2, content: 3
Index: 1, content: 2
Index: 0, content: 1

do{} while() can help you to use unsigned types of variable for loop without integer overflow:

// main.c
#include <stdio.h>

int main(void)
{

    int array[] = {1,2,3,4,5,6,7,8,9,10};
    unsigned int size = sizeof(array)/sizeof(int); // size == 10;

    unsigned int i = size;
    do
    {
        i--;
        printf("Index: %u, content: %d\n",i,array[i]);

    } while(i > 0);

    return 0;
}

And compile it with:

gcc -std=c11 -Wall -Wextra -Wpedantic main.c

Output:

Index: 9, content: 10
Index: 8, content: 9
Index: 7, content: 8
Index: 6, content: 7
Index: 5, content: 6
Index: 4, content: 5
Index: 3, content: 4
Index: 2, content: 3
Index: 1, content: 2
Index: 0, content: 1
中性美 2024-10-25 04:23:01

Centos 7 x86_64 中的 gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) 不会给出警告。

但是,当循环索引递减到 -1 时,循环索引会隐式转换为等于 UINT_MAX 的值 (limits.h)

UINT_MAX + 1u 等于 00 - 1 等于 UINX_MAX

limits.h ANSI 提出的各种与平台相关的常量

替代解决方案之一是:

unsigned int clLoop, i;

for(i = cpLoopStart+1, clLoop = i-1; i > 0; i--, clLoop = i-1)                                  
{
    //Do something
}

i 将在 [1, cpLoopStart+1] 范围内变化

clLoop 将在范围 [1, cpLoopStart+1] 内变化[0,cpLoopStart]

gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) in Centos 7 x86_64 does not give the warning.

But when loop index is decremented to -1, loop index is implicitly converted to a value which is equal to UINT_MAX (limits.h)

UINT_MAX + 1u is equal to 0. 0 - 1 is equal to UINX_MAX.

limits.h Various platform-dependent constants proposed by ANSI

One of alternative solution is:

unsigned int clLoop, i;

for(i = cpLoopStart+1, clLoop = i-1; i > 0; i--, clLoop = i-1)                                  
{
    //Do something
}

i will change in the range [1, cpLoopStart+1]

clLoop will change in the range [0, cpLoopStart]

唔猫 2024-10-25 04:23:01

中删除 =

clLoop >= 0

您应该在假设您的 cpLoopStart is 5

。那么,进一步迭代中的 clLoop 值将是 -

clLoop = 4;
clLoop = 3;
clLoop = 2;
clLoop = 1;
clLoop = 0;
clLoop = 0;
clLoop = 0;
clLoop = 0;
|
|
|
Infinite times.

You should remove = in

clLoop >= 0

Let's say your cpLoopStart is 5.

Then, clLoop value in the further iteratiosn would be -

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