web-dev-qa-db-ja.com

Unsigned Int> = 0の比較が「無意味な比較」であるのはなぜですか?

私は警告を受けました:

Pe186「符号なし整数とゼロの無意味な比較」

次のコードをコンパイルしようとしたとき:

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

理由がわかりません。 unsigned intが負になることはないので、[より小ゼロ]という値を探していれば理解できました。しかし、私がここで探しているのは、それがequal to zeroである場合だけです。これは、unsigned intが確かに可能です。

このループでポストデクリメントの代わりにプレデクリメントを試みた場合にも、このエラーが発生する可能性がありますが、これは当てはまりません。

19
Josh

Unsigned intが(>=) ゼロ。符号なし整数はゼロ未満になることはないため、この式は常に真になります。

コンパイラは、無限ループをプログラムしようとしていることを警告しようとします。

45
Timbo

Unsigned intが等しいまたはより大きい 0であるかどうかを確認しています。これは常に真です。

8
Ole Begemann

符号なし整数は、無限にデクリメントした後(つまり、clLoop >= 0は常にtrueになります)。これにより、比較が無意味になります。

4
vtha

あなたが言うつもりだったと思う

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

clLoop >= 0は常にtrueです。デクリメントする前でもデクリメントする後でも、符号なしの値は少なくとも0です。0をデクリメントすると、UINT_MAXが得られます。

コンパイラは、おそらくmeanを永久にループしない(または、別の構文を使用した場合は、より明らかに永久にループする)とは考えないため、警告が表示されます。

2
Steve Jessop

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
1
Dennis V.R.

警告は、forループブレーク条件clLoop >= 0について不平を言います。 clLoopが負になるとループは終了しますが、unsigned intの場合はループは発生しません。

1
schnaader

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によって提案されたさまざまなプラットフォーム依存の定数

代替ソリューションの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]の範囲で変化します

0
Nick Dong

=を削除する必要があります

clLoop >= 0

cpLoopStart is 5としましょう。

次に、さらなる反復のclLoop値は-

clLoop = 4;
clLoop = 3;
clLoop = 2;
clLoop = 1;
clLoop = 0;
clLoop = 0;
clLoop = 0;
clLoop = 0;
|
|
|
Infinite times.
0
Mayank Jindal