Wird der Vergleich zwischen vorzeichenbehafteten und vorzeichenlosen Integer-Ausdrücken tatsächlich zu Fehlern führen?

8

Oft wird ein Objekt, das ich verwende, int -Parameter haben (signiert) (z. B. int iSize ), die schließlich speichern, wie groß etwas sein sollte. Zur selben Zeit initialisiere ich sie oft auf -1 , um anzuzeigen, dass das Objekt (etc) nicht eingerichtet wurde / nicht gefüllt wurde / nicht bereit ist zu verwenden.

Ich habe oft die Warnung comparison between signed and unsigned integer , wenn ich etwas wie if( iSize >= someVector.size() ) { ... } mache.

Ich möchte also nicht ein unsigned int verwenden. Gibt es Situationen, in denen dies zu einem Fehler oder unerwartetem Verhalten führt?

Wenn nicht: Was ist der beste Weg, damit umzugehen? Wenn ich das Compiler-Flag -Wno-sign-compare verwende, könnte ich (hypothetisch) eine Situation übersehen, in der ich sollte eine unsigned int (oder so ähnlich) verwenden sollte. Sollte ich also einen Cast verwenden, wenn ich mit einem unsigned int vergleiche - z. if( iSize >= (int)someVector.size() ) { ... } ?

    
DilithiumMatrix 27.01.2013, 22:22
quelle

1 Antwort

5

Ja, es gibt und sehr subtile. Wenn Sie neugierig sind, können Sie diese interessante Präsentation von Stephan T. Lavavej über die arithmetische Konvertierung und einen Fehler in der Microsoft-Implementierung von STL, der nur durch einen signierten vs unsignierten Vergleich verursacht wurde.

Im Allgemeinen beruht das Problem auf der Tatsache, dass aufgrund der Komplement-2-Arithmetik ein sehr kleiner negativer Integralwert dieselbe Bitdarstellung wie ein sehr großer vorzeichenloser Integralwert (z. B. -1 = 0xFFFF = 65535 ) aufweist.

Warum sollten Sie im speziellen Fall von size() nicht den Typ size_t für iSize verwenden? Vorzeichenlose Werte geben Ihnen mehr Ausdruckskraft, verwenden Sie sie.

Und wenn Sie iSize nicht als size_t deklarieren möchten, machen Sie es einfach klar, indem Sie eine explizite Umwandlung verwenden, bei der Ihnen die Art dieses Vergleichs bekannt ist. Der Compiler versucht, Ihnen mit diesen Warnungen einen Gefallen zu tun, und wie Sie richtig geschrieben haben, könnte es Situationen geben, in denen das Ignorieren von ihnen Ihnen sehr starke Kopfschmerzen bereiten würde.

Wenn also iSize manchmal negativ ist (und als weniger als alle unsigned int -Werte von size() bewertet werden sollte), verwenden Sie das idiom: if ((iSize < 0) || ((unsigned)iSize < somevector.size())) ...

    
Andy Prowl 27.01.2013, 22:36
quelle