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

这一生的挚爱 提交于 2019-12-03 22:35:15

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.

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

vtha

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

I think you meant to say

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

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.

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.

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

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]

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