Ist der Vergleich ein BOOLESCHER Wert, gegen die JA gefährlich?
Fand ich einen Kommentar heute in einer Quellcode-Datei:
// - no longer compare BOOL against YES (dangerous!)
Ist der Vergleich BOOL
gegen YES
in Objective-C wirklich so gefährlich? Und warum ist das so?
Kann der Wert von YES
ändern während der Laufzeit? Vielleicht NO
ist immer 0
aber YES
werden kann 1
, 2
oder 3
- je nach Laufzeit-compiler, deine verlinkten frameworks?
- Siehe diese Frage: stackoverflow.com/questions/690903/...
- BTW, im 64-bit-iOS-Ziele
BOOL
jetzt übersetztbool
, das ist ein richtiger Typ "boolean". Aber historisch gesehen, war es nur einesigned char
, und unter Berücksichtigung aller Vorsichtsmaßnahmen, die wir sehen, werden unten diskutiert.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist, dass die BOOL ist nicht von einem einheitlichen Typ, sondern eine Typdefinition:
Als char, seine Werte sind nicht gezwungen, an
TRUE
undFALSE
. Was passiert mit einem anderen Wert?BOOL
mit so etwas wiebitMask & (1 << 2)
ist eine durchaus vernünftige Sache zu tun, und kann eine "beliebige" truthy-Wert (mindestens ein bit gesetzt), der nicht gleichYES
(nur LSB-set). SieheBOOL
's scharfen Ecken im BNR für mehr.Sollte man sich nie vergleichen Boolesche Werte gegen alles in einer der C-basierten Sprachen. Der richtige Weg, es zu tun ist, um entweder:
oder:
Dies macht den code sehr viel besser lesbar (vor allem, wenn Sie mit intelligent benannte Variablen und Funktionen, wie
isPrime(n)
oderchildThreadHasFinished
) und safe. Der Grund, so etwas wie:nicht so sicher ist, dass es tatsächlich eine große Anzahl von Werten der
b
wird zu true ausgewertet, und derTRUE
ist nur einer von Ihnen.Folgendes:
Sollten Sie sich beide diese Zeilen ausgedruckt, wenn es funktioniert wie erwartet, aber Sie erhalten nur die erste. Das ist, weil 7 ist tatsächlich wahr, wenn Sie korrekt behandelt werden (0 ist false, alles andere true ist), aber das explizite testen auf Gleichheit zu false ausgewertet wird.
Update:
In Antwort auf Ihren Kommentar, dass Sie dachte, es wäre mehr als coder Dummheit: ja, es gibt (aber ich würde trotzdem nicht Rabatt-coder Dummheit als Grund genug, den defensiven Programmierung ist immer eine gute Idee).
Ich erwähnte auch die Lesbarkeit, die ist ziemlich hoch auf meiner Liste der wünschenswerten Eigenschaften in code.
Einen Zustand sollte, ist entweder ein Vergleich zwischen Objekten oder ein flag (einschließlich booleschen Werte):
Wenn Sie (wie ich denke) ein Greuel wie:
wo wollen Sie aufhören:
und so weiter.
Den Recht Weg, es zu tun für eine bessere Lesbarkeit ist nur entsprechend dem Namen flag-Variablen.
All dies wahr ist, aber es gibt triftige Gegenargumente in Betracht:
— Vielleicht haben wir wollen zu überprüfen, ein BOOL ist eigentlich ein JA oder NEIN. Wirklich, die Speicherung beliebiger anderer Wert als 0 oder 1 in ein BOOL ist ziemlich falsch. Wenn es passiert, ist es nicht mehr wahrscheinlich, weil ein Fehler irgendwo anders in der codebase, und ist nicht explizit überprüft JA nur die Maskierung dieser Fehler? Ich denke, dies ist viel wahrscheinlicher als ein schlampiger Programmierer mit BOOL in einem nicht-standard-Weg. Also, ich denke, ich würde wollen meinen tests fehl, wenn Sie meinen BOOL nicht JA, wenn ich bin auf der Suche nach der Wahrheit.
Ich nicht unbedingt damit einverstanden, dass "wenn (isWhatever)" ist leichter lesbar, besonders bei der Bewertung lang, aber ansonsten gut lesbar, Funktionsaufrufe,
vgl.
mit:
Die erste ist der Vergleich gegen true, die zweite gegen die falschen und es ist schwer zu sagen, der Unterschied, wenn man schnell Lesen, code, Recht?
Vergleichen:
und
...und ist es nicht viel mehr lesbar?
Wieder, ich sage nicht ein Weg ist richtig und die andere falsch ist, aber es gibt einige Kontrapunkte.
Wenn der code verwendet eine
BOOL
variabel, es soll eine solche variable als boolean. Der compiler überprüft nicht, ob eineBOOL
variable bekommt einen anderen Wert, in der gleichen Weise, die der compiler überprüft nicht, ob Sie initialisieren eine variable an eine Methode übergeben, mit einem Wert, der zwischen einer Reihe von Konstanten.