2016-08-21 5 views
0

私が取り組んでいたプログラムのバグに気づき、コードを抽出しました。これは基本的にはこれです。
それは無限ループで署名したint型と結果と符号なしの比較を行います。C++符号なし無限ループ比較バグ

#include <iostream> 

int main() 
{ 
    unsigned int i = 0; 
    while (i < 1000000) 
    { 
     printf("%o\n", i); 
     ++i; 
    } 
    return 0; 
} 

私が代わりにこれを使用してみました:

私は署名/符号なしの比較を修正するだろうと思った
#include <iostream> 

int main() 
{ 
    unsigned int i = 0; 
    while (i < 1000000u) 
    { 
     printf("%o\n", i); 
     ++i; 
    } 
    return 0; 
} 

をし、それはまだ無限ループに当たっています。だから、私はunsigned intにダイキャストしようとしましたが、サイコロは無限ループです。

Visual Studio 2015を使用すると、完全な最適化がリリースされます。

+6

あなたはそれが無限ループだと確信していますか?これは私にとって非常に長いループのように見えます。特に印刷にはかなりの時間がかかります。 'i + = 1000'に変更して、終了条件が機能するかどうかを確認してください。 – dasblinkenlight

+0

これは、符号付き/符号なし比較の問題ではありません。値 '1000000'は両方の範囲にあり、これが理由であると仮定して問題を解決しようとしましたが、機能しませんでした。 – AhmadWabbi

+1

なぜ#include 'ですが、' printf'を使用しますか? – dxiv

答えて

3

を使用する必要があります無限ループに入ると思うようになります。 %oパラメータを%uに変更すると、問題が明らかになることがあります。

+0

明らかに本当です、std :: cout << std: :oct << n << '\ n'は、基本整数を8進数に変更します。これは元々使用していたものです –

1

これは、int型のオーバーフローが原因です。タイプlimitsを参照してください。そのような膨大な数の比較のために、私はwin7のもUbuntuの(64ビットの両方)の無限ループを再現することはできませんが、私は問題がどの符号なし進数表現であなたのprintf()関数であると考えている代わりにlongint

+0

よりもはるかに大きいかもしれませんが、最近のほとんどのプラットフォームでは 'int'は少なくとも32ビットです。 – Blorgbeard

+1

そうは思わない。デフォルトのint型が32ビットで、 '1000000'よりはるかに広いVS2015が挙げられます。 – dxiv

+0

とVC++でコンパイルされた64ビットは、数値を出力しますが、限界に達するまで停止しません。そして、符号なしの規則のために、それはまだ止まらず、ちょうど –

関連する問題