2017-01-24 20 views
1

私は数学的なバグになると思いますが、なぜそれが起こっているのか完全に理解していません。C++ if文の数学的評価のバグ

if (mNextBottomIndex < mBlocks.size() - 1) { 
    if (mBlocks[mNextBottomIndex + 1]->getGlobalPosition().y >= -mBlocks[mNextBottomIndex + 1]->getHeight()) { 
    mBlocks[mNextBottomIndex + 1]->setAlpha(1.0f); 
    mNextBottomIndex++; 
    } 
} 

mBlocks.size() = 0mNextBottomIndex = 3(またはmNextBottomIndex> 0任意の数に等しい)ので、それはinner if statementの評価にクラッシュです。だから私の質問は、最後の文で変数が与えられた場合、どのようにそれがouter if statementを過ぎていますか?アプリケーションがバックグラウンドスレッドでこれらの変数を処理していない、と変数は前と同じであり、outer if statement

後、私は

if (mBlocks.size() != 0 && mNextBottomIndex < mBlocks.size() - 1) { 
    if (mBlocks[mNextBottomIndex + 1]->getGlobalPosition().y >= -mBlocks[mNextBottomIndex + 1]->getHeight()) { 
    mBlocks[mNextBottomIndex + 1]->setAlpha(1.0f); 
    mNextBottomIndex++; 
    } 
} 

する外if statementを修正し、それがクラッシュしていないようです今。

+2

場合 'mBlocks.size()'戻り符号なしの値、 'mBlocks.size() - 1 '、' mBlocks.size()'戻ります'0'、通常_非常に大きな数(その型の最大数)にラップアラウンドします。 –

+2

@AlgirdasPreidžiusは「通常」ではなく、*常に*です。符号なし演算がラップするように指定されています。 – Quentin

+0

@Quentinそして、このステートメントは、以下の引用に照らして常に私を混乱させました:_式の評価中に結果が数学的に定義されていないか、またはそのタイプの表現可能な値の範囲が でない場合、 -1 'は符号なし型の表現可能な値の範囲にないため、技術的には未定義であるべきです。 –

答えて

9

mBlocks.size()は符号なし整数です。 値0の符号なし整数から1を引いた値が大きい正の数にアンダーフローします。

+0

あなたは0からの意味ですが、あなたは正しいです。 – AndyG

2

あなたは私たちにmBlocksの種類を示していますが、std::vectorsize() member function呼び出していることを考えるとしていない(またはいくつかの類似したSTDLIBコンテナを、例えばstd::array)、戻り値の型は、(cppreference @std::vector::sizeから)タイプsize_typeは次のとおりです。ある

std::vector::size

size_type size() const; 

std::vectorからcppreference @)常に符号なし整数:(通常std::size_t

メンバーの種類

...

size_type符号なし整数型

あなたは1を引きます0から、符号なしの型で負の数を生成します(この負の数が小さい場合は)という述語を当然trueとして渡す大きな符号なし整数にラップアラウンドします。

も参照してください。次