我收到了警告:
Pe186“无符号int与零的无意义比较”
当我尝试编译以下代码时:
for(clLoop = cpLoopStart; clLoop >= 0; clLoop--)
{
//Do something
}
我不明白为什么。我能理解,如果我正在寻找小于零的值,因为unsigned int
永远不会是负数。但我在这里寻找的只是它等于为零,unsigned int
当然可以。
如果在这个循环中我试图预先递减而不是后递减,我甚至可以看到这个错误,但事实并非如此。
答案 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)
但是当循环索引递减到-1
时,循环索引会隐式转换为等于UINT_MAX(withRouter
)的值
UINT_MAX + 1u is equal to 0
。 0 - 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”,这使得在比较值和变量时也更加清楚。