Ungläubiges Staunen bei Vergleich int > Zahl



  • Hallo zusammen,

    ich überprüfe in einer if-Bedingung, ob ein Index (iIdx) innerhalb eines Arrays liegt. Wenn nicht, dann abbrechen.

    int iIdx = 0;
    vector<TPoint> vPoint;
    if(iIdx > vPoint.size()-1){
        return;
    }
    

    Nur leider muss ich feststellen, dass dieser Vergleich nicht das gewünschte Ergebnis liefert, wie die Ergebnisse der folgenden kleinen Testreihe zeigen:

    int iIdx = 0;
    vector<TPoint> vPoint;
    
    int iTemp = vPoint.size()-1;
    bool b = iIdx > iTemp; // true
    bool b1 = iIdx > vPoint.size()-1; // false
    bool b2 = iIdx > (int)(vPoint.size()-1); // true
    bool b3 = 0 > -1;  // true
    

    In obigem Beispiel funktioniert es, wenn ich (vPoint.size()-1) nach int caste.
    Nur warum funktioniert dieser Vergleich in for-Schleifen (seit Jahren)?

    for(int i=0; i < vPoint.size(); i++){
        //(...)
    }
    

    Gruß
    Leo



  • Auch wenn mich dies an dieser Stelle etwas verwundert, könnte es daran liegen das "size()" ein "unsigned"-Wert ist. Je nachdem in welcher Reihenfolge die Umrechnung erfolgen kann 0-1 entweder -1 oder einen ziemlich großen unsigned-Wert (Überlauf) ergeben.



  • Hallo Leo,

    darum solltest du auch besser auf

    if(iIdx >= vPoint.size()){
        return;
    }
    

    testen.

    Btw. teste mal

    bool b3 = 0 > (unsigned)-1;
    

    Dann müßte auch 'false' rauskommen...



  • Das Verhalten ist so im Standard festgelegt. In Paragraph 5 Absatz 10 steht unter anderem

    Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.

    Das dürfte hier zutreffen. Wir haben bei vPoint.size()-1 ein unsigned int (vPoint.size()) und int (die 1) die beide vom gleichen Rang sind (§4.13 - integral conversion rank). Also wird int zu unsigned int konvertiert. Das Ergebnis einer Operation zweier unsigned int ist wieder ein unsigned int. Also folgt der Überlauf (siehe hier auch §4.7 - Integral conversions).
    Das ist jetzt aus dem aktuellen Standard.


Anmelden zum Antworten