Kann ich für jeden C ++ - Compiler (bool) true == (int) 1 annehmen?

117

Kann ich (bool)true == (int)1für jeden C ++ - Compiler annehmen ?

Petruza
quelle
3
Die Besetzungen in Ihrer Frage sind überflüssig, sollten sie umgekehrt werden?
GManNickG
9
Er meint nicht, dass sie Casts sind, er meintbool t = true; int n = 1; if (t == n) {...} ;
Egrunin
7
@egrunin: Eh, aber true ist ein Bool und 1 ist sowieso ein Int. :)
GManNickG
1
Richtig, ich wollte den Typ der Werte angeben.
Petruza
2
(int) trueist 1als ganzzahliger Wert, aber etwas, if (pointer)das durch den then-Teil geht, wenn pointer != 0. Das einzige, was Sie als wahr annehmen können, ist das false == 0, und true != 0(und truebewertet, 1wenn es besetzt wird int)
Luis Colorado

Antworten:

133

Ja. Die Abgüsse sind überflüssig. In deinem Ausdruck:

true == 1

Es gilt eine integrale Promotion und der Bool-Wert wird zu einem befördert, intund diese Promotion muss 1 ergeben.

Referenz: 4.7 [conv.integral] / 4: Wenn der Quelltyp bool... trueist, wird er in eins konvertiert.

CB Bailey
quelle
9
@Joshua: trueist ein Schlüsselwort, das von der Sprache definiert wird. Es kann nicht von einer Bibliothek neu definiert werden. #defines dürfen Schlüsselwörter nicht neu definieren.
Jalf
21
@jalf: # define's dürfen tatsächlich Systemschlüsselwörter definieren. Die Vorverarbeitungsphase der C-Kompilierung ist rein textuell und kennt weder Schlüsselwörter noch die C-Syntax im Allgemeinen. Trotzdem ist es natürlich fast immer eine schlechte Idee, Sprachschlüsselwörter neu zu definieren.
Dale Hagglund
2
@ Jalf. Sie sind nicht? Siehe gcc.gnu.org/onlinedocs/cpp/Macros.html und mindestens einen der Einträge im International Obfuscated C Code Contest, bei dem einmal gefragt wurde: "Wann dauert whileeine Weile nicht?" : (Antwort , wenn es nimmt zwei Parameter, denn dann wird dieser Eintrag hatte #definedes printf.)
Ken Bloom
3
In C99, §6.10.1 / 1 heißt es: "Der Ausdruck, der die bedingte Einbeziehung steuert, muss ein ganzzahliger konstanter Ausdruck sein, mit der Ausnahme, dass: er keine Besetzung enthält; Bezeichner (einschließlich derjenigen, die lexikalisch mit Schlüsselwörtern identisch sind) werden wie nachstehend beschrieben interpretiert." Obwohl dies nicht als direkte Berechtigung angegeben ist, sieht dies eindeutig die Möglichkeit eines Makros vor, das "lexikalisch identisch" mit einem Schlüsselwort ist.
Jerry Coffin
2
Oh, und #defines dürfen Schlüsselwörter neu definieren. C ++ 1x verursachte zu viele Probleme mit seinen neuen Schlüsselwörtern, sodass die Anforderung entfernt werden musste.
Joshua
18

Charles Baileys Antwort ist richtig. Der genaue Wortlaut des C ++ - Standards lautet (§4.7 / 4): "Wenn der Quelltyp bool ist, wird der Wert false in null und der Wert true in eins konvertiert."

Bearbeiten: Ich sehe, dass er auch die Referenz hinzugefügt hat - ich werde diese in Kürze löschen, wenn ich nicht abgelenkt werde und vergesse ...

Edit2: Andererseits ist es wahrscheinlich erwähnenswert, dass, während die Booleschen Werte selbst immer in Null oder Eins konvertiert werden, eine Reihe von Funktionen (insbesondere aus der C-Standardbibliothek) Werte zurückgeben, die "im Grunde Boolesch" sind, aber als ints dargestellt werden Normalerweise muss nur Null sein, um falsch anzuzeigen, oder ungleich Null, um wahr anzuzeigen. Zum Beispiel <ctype.h>erfordern die is * -Funktionen nur Null oder Nicht-Null, nicht unbedingt Null oder Eins.

Wenn Sie dies in " bool0" umwandeln, wird "Null" in "Falsch" und "Nicht Null" in "Wahr" umgewandelt (wie erwartet).

Jerry Sarg
quelle
9

Nach dem Standard sollten Sie mit dieser Annahme sicher sein. Der C ++ - boolTyp hat zwei Werte - trueund die falseentsprechenden Werte 1 und 0.

Achten Sie darauf, boolAusdrücke und Variablen mit BOOLAusdrücken und Variablen zu mischen . Letzteres ist definiert als FALSE = 0und TRUE != FALSE, was in der Praxis häufig bedeutet, dass jeder von 0 abweichende Wert berücksichtigt wird TRUE.

Viele moderne Compiler geben tatsächlich eine Warnung für jeden Code aus, der implizit versucht, von BOOLbis zu konvertieren , boolwenn der BOOLWert von 0 oder 1 abweicht.

Franci Penov
quelle
3

Ich habe festgestellt, dass verschiedene Compiler bei true unterschiedliche Ergebnisse zurückgeben. Ich habe auch festgestellt, dass es fast immer besser ist, einen Bool mit einem Bool anstelle eines Int zu vergleichen. Diese Ints neigen dazu, den Wert im Laufe der Zeit zu ändern, wenn sich Ihr Programm weiterentwickelt. Wenn Sie als 1 wahr annehmen, können Sie von einer nicht verwandten Änderung an anderer Stelle in Ihrem Code gebissen werden.

Michael Dorgan
quelle
3
Dies ist eine falsche Antwort für C ++, ebenso truewie ein Sprachschlüsselwort mit definiertem Verhalten. Wenn Sie sich auf ein allgemein definiertes Makro wie beziehen TRUE, ist es korrekt.
David Thornley
1
Könnte meine Erfahrung mit C-Compilern sein - ich habe im Laufe der Jahre viel Zeit mit ihnen verbracht. Mein Punkt über die direkte Verwendung mathematischer Ausdrücke in if-Anweisungen steht jedoch. Wir hatten Code, der sah, ob eine Bitverschiebung in einem Wenn nicht Null war, dann nahm jemand anderes denselben Wert ungleich Null und nahm an, dass es 1 war, und sprengte Sachen in die Luft. Eine einfache Konvertierung in true / 1 hätte dies verhindert.
Michael Dorgan
Ich habe auch ein solches Verhalten gesehen. Zugegeben, das letzte Mal, dass ich es sah, war ungefähr 1999. Ich benutzte GCC. Die Sprache war C. Trotzdem habe ich tatsächlich ein solches Verhalten gesehen.
15.