私は警告を受けました:
Pe186「符号なし整数とゼロの無意味な比較」
次のコードをコンパイルしようとしたとき:
for(clLoop = cpLoopStart; clLoop >= 0; clLoop--)
{
//Do something
}
理由がわかりません。 unsigned int
が負になることはないので、[より小ゼロ]という値を探していれば理解できました。しかし、私がここで探しているのは、それがequal to zeroである場合だけです。これは、unsigned int
が確かに可能です。
このループでポストデクリメントの代わりにプレデクリメントを試みた場合にも、このエラーが発生する可能性がありますが、これは当てはまりません。
Unsigned intが(>=
) ゼロ。符号なし整数はゼロ未満になることはないため、この式は常に真になります。
コンパイラは、無限ループをプログラムしようとしていることを警告しようとします。
Unsigned intが等しいまたはより大きい 0であるかどうかを確認しています。これは常に真です。
符号なし整数は、無限にデクリメントした後(つまり、clLoop >= 0
は常にtrueになります)。これにより、比較が無意味になります。
あなたが言うつもりだったと思う
for(clLoop = cpLoopStart; clLoop; clLoop--)
{ //Do something
}
clLoop >= 0
は常にtrueです。デクリメントする前でもデクリメントする後でも、符号なしの値は少なくとも0です。0
をデクリメントすると、UINT_MAX
が得られます。
コンパイラは、おそらくmeanを永久にループしない(または、別の構文を使用した場合は、より明らかに永久にループする)とは考えないため、警告が表示されます。
do {} while()は、整数オーバーフローなしで符号なしタイプの変数forループを使用するのに役立ちます。
// 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
警告は、for
ループブレーク条件clLoop >= 0
について不平を言います。 clLoop
が負になるとループは終了しますが、unsigned intの場合はループは発生しません。
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 0
。 0 - 1 is equal to UINX_MAX
。
limits.h ANSIによって提案されたさまざまなプラットフォーム依存の定数
代替ソリューションの1つは次のとおりです。
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]の範囲で変化します
=
を削除する必要があります
clLoop >= 0
cpLoopStart is 5
としましょう。
次に、さらなる反復のclLoop値は-
clLoop = 4;
clLoop = 3;
clLoop = 2;
clLoop = 1;
clLoop = 0;
clLoop = 0;
clLoop = 0;
clLoop = 0;
|
|
|
Infinite times.