为什么比较无符号Int> = 0“无意义比较”?

时间:2011-02-21 13:12:31

标签: c++ c for-loop comparison unsigned

我收到了警告:

  

Pe186“无符号int与零的无意义比较”

当我尝试编译以下代码时:

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

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

如果在这个循环中我试图预先递减而不是后递减,我甚至可以看到这个错误,但事实并非如此。

10 个答案:

答案 0 :(得分:45)

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

编译器试图警告您即将编程无限循环。

答案 1 :(得分:8)

您正在检查unsigned int是否等于或大于 0.这始终是真的。

答案 2 :(得分:4)

无符号整数即使在无限递减后也不会低于0(即clLoop >= 0总是为真),这使得比较毫无意义。

答案 3 :(得分:3)

我想你想说

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

答案 4 :(得分:2)

clLoop >= 0永远是真的。无论是预先递减还是后递减都无关紧要,无符号值至少为0.当您递减0时,得到UINT_MAX

编译器认为您可能不会意味着永远循环(或者您使用了不同的构造,更明显地循环),因此警告。

答案 5 :(得分:1)

警告会抱怨您的for循环中断条件clLoop >= 0。如果clLoop变为负数,循环将结束,但对于unsigned int,这将永远不会发生。

答案 6 :(得分:1)

do {} while()可以帮助您在没有整数溢出的情况下使用无符号类型的变量:

// 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

答案 7 :(得分:0)

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

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

UINT_MAX + 1u is equal to 00 - 1 is equal to 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将在[0,cpLoopStart]

范围内更改

答案 8 :(得分:0)

您应在

中删除=
clLoop >= 0

假设您的cpLoopStart is 5

然后,进一步迭代中的clLoop值为-

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

答案 9 :(得分:0)

正如其他人已经指出的那样,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”,这使得在比较值和变量时也更加清楚。