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

我收到警告:

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

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

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

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

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

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

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

您正在检查unsigned int是否等于或大于 0.这总是正确的。

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

我想你想说

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

clLoop >= 0始终为true。 无论是预先递减还是后递减都无关紧要,无符号值至少为0.当您递减0您将得到UINT_MAX

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

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

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

 // main.c #include  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 

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

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

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]范围内变化