Why Is Comparing if an Unsigned Int >= 0 a “Pointless Comparison”?

白昼怎懂夜的黑 提交于 2019-12-09 14:09:28

问题


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.


回答1:


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.




回答2:


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




回答3:


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




回答4:


I think you meant to say

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



回答5:


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.




回答6:


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.




回答7:


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



回答8:


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]




回答9:


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.


来源:https://stackoverflow.com/questions/5066362/why-is-comparing-if-an-unsigned-int-0-a-pointless-comparison

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!