Unter MSVC Version 10, kompiliert als C++-Code, GCC 4.6.3-ubuntu5 kompiliert als C-Code und G++ 4.6.3-1ubuntu5 kompiliert als C++-Code, erhalten Sie nur
false < true
Das heißt, die folgenden Ungleichungen sind alle false:
(bool)-1 < true
(bool)-1 < false
true < false
Und das Folgende ist true:
false < true
James Kanze
In C++ (und ich vermute auch in C), bools vergleichen genau so, als ob false war 0 und true war 1. Und wenn der Typ ist boolkeine Werte außer true und false Sind möglich.
Beim Vergleichen bool zu anderen numerischen Typen, wird es konvertiert intwieder mit false Umwandlung in 0 und true Umwandlung in 1.
Bearbeiten: Sowohl C++ als auch stdbool.h in C99 auch erzwingen, dass boolesche Werte entweder 0 (falsch) oder 1 (wahr) sind – bool b = -1; setzt den Wert von b zu 1. Seit 1 < 1 und 1 < 0 beide falsch sind, sind die Ungleichungen in der Frage richtig.
Bearbeiten: (von James) Abgesehen davon, dass die obige Bearbeitung nicht wirklich korrekt ist, zumindest für C++. EIN bool hat keinen Wert von 0 oder 1, es hat einen Wert von false oder true. Es ist nur, wenn es befördert wird int dass die Konvertierung die Werte von erstellt 0 und 1.
Und wie Konrad darauf hingewiesen hat, gibt es keinen Vergleich bool Werte. Für die Vergleichsoperatoren erfolgen die “üblichen arithmetischen Umrechnungen”, das heißt ganzzahlige Fortschreibung auf beide Operanden, das heißt bool konvertiert zu int (ebenso wie char oder short… oder eine Aufzählung).
Alles ziemlich technisch. In der Praxis kann man sich das merken false < trueoder Sie können überlegen false ist 0 und true ist 1, je nachdem, was für Sie am besten funktioniert. Das einzig Wichtige, an das Sie sich erinnern sollten, ist, dass a bool haben kann nein andere Werte.
(Interessanterweise glaube ich nicht, dass die Bitmuster von a bool werden von der Norm vorgegeben. Eine Implementierung könnte die Bitmuster verwenden 0x55 und 0xAAzum Beispiel, solange alle Konvertierungen in einen ganzzahligen Typ 0 und 1 ergaben, Konvertierung in bool gab immer den passenden Wert usw. Einschließlich Nullinitialisierung statischer Variablen.)
Und eine letzte Anmerkung: bool b = -1; setzt b zu -1 != 0 (welches ist truenicht 1aber natürlich, true wird umwandeln 1 in jedem Zahlenkontext.
Finden Sie heraus, wo dies im Standard definiert ist? Ich habe gerade gesucht und konnte es nicht finden (ich bin mir nicht einmal sicher, wonach ich suchen soll).
– Konrad Rudolf
14. August 2012 um 12:07 Uhr
@Mansuro Irrelevant, James und ich haben über C++ gesprochen. Aber selbst für C sagt nichts in diesem Dokument aus, wie eine Konvertierung durchgeführt wird (bool) -1 gehandhabt wird.
– Konrad Rudolf
14. August 2012 um 12:10 Uhr
§4.5 Integrale Werbeaktionen. “Ein rvalue vom Typ bool kann in einen rvalue vom Typ konvertiert werden intmit false Null werden und true eins werden.” (Beachte, dass a bool hat nie einen Wert von 0 oder 1; nur false und true. Deshalb sagte ich “genau als ob.”) Und §4.12 für die Konvertierungen zu bool.
– James Kanze
14. August 2012 um 12:13 Uhr
Ja, aber wo definiert es ihre Reihenfolge? EDIT: Duh, vergiss es.
– Konrad Rudolf
14. August 2012 um 12:13 Uhr
@KonradRudolph: Es gibt keine eigentliche Bestellung bool. Wie bei vielen anderen Operationen wird der Wert auf befördert int Befolgen Sie die obigen Regeln, und dann werden zwei Ints verglichen.
– David Rodríguez – Dribeas
14. August 2012 um 12:14 Uhr
Das macht durchaus Sinn. Die integrale Typ => Bool-Konvertierung ist effektiv b = i != 0. Um das zu tun < Vergleich es fördert die bool zu int durch die Regel false=>0 und true=>1. In deinem ersten Fall -1 entspricht true, und beide werden auf 1 hochgestuft, also ist es false. Offensichtlich ist 1 im zweiten und dritten Fall niemals kleiner als 0, während 0 < 1 im letzten Fall.
Operator > und < basieren darauf:
true == (1)
false == (0)
dies falsch: (bool)-1 < wahr (bool)-1 < falsch wegen rollierender Arithmetik in bool b = -1;
Nur für C++ false < true
Für C ist schwieriger zu beantworten. Aha
typedef char _Bool; /* For C compilers without _Bool */ in meiner stdbool.h
Scheint, dass wenn Compiler-Unterstützung _Bool es funktioniert wie in C++ und konvertiert automatisch in 0/1, aber wenn nicht, sollte es als char funktionieren und es wird sein b < true, b < false wenn char signiert ist
Für mich ist (int)(bool) -1 sogar in C 1, also bool ist definiert als nicht char
Boolesche Werte werden so geordnet, dass false ist kleiner als true. Nach der Norm ist a bool kann nur zwei Werte enthalten: true und falsealso die Konvertierungen in (bool)-1 hätte nachgeben sollen true (wie alle Nicht-0-Werte, wenn sie in Bool konvertiert werden true). Das ist das Verhalten in clang und g++-4.7.
Der eigentliche Vergleich (glaube ich) ist erledigt int nach dem bool wird hochgestuft, und es scheint, dass die von Ihnen getesteten Compiler den Zwischenschritt der Konvertierung durch bool vermieden und nur das eigentliche hochgestuft haben bool Wert.
bool scheint als (vorzeichenbehafteter) Integer-Typ definiert zu sein, wobei false 0 und null 1 ist. Dies erklärt, warum true > false (1 > 0) wahr ist.
Außerdem bewirkt der Vergleich von -1 mit einer Zahl ohne Vorzeichen, dass -1 in eine Zahl ohne Vorzeichen umgewandelt wird, und auf Ihrer Plattform führt dies zu einem Ganzzahlüberlauf, der zu UINT_MAX führt (oder zu welchem Typ bool typdefiniert wurde). Dies erklärt nun, warum die folgenden Ausdrücke falsch waren:
((bool)-1) < true i. e. UINT_MAX < 1
((bool)-1) < false i. e. UINT_MAX < 0
true < false i. e. 1 < 0
Alexander Tschertow
Hier ist eine Erklärung, ich habe es jedoch nicht mit dem Standard überprüft. Aus Ihren Experimenten scheint der Operator “<" nicht für boolesche Werte definiert zu sein. Was verglichen wird, sind die unsigned ints, in die die booleschen Werte konvertiert werden. Theoretisch könnte es möglich sein, dass der Standard nicht garantiert, dass alle "wahren" booleschen Werte in denselben Wert konvertiert werden. Und -1 wird in das größte unsigned int umgewandelt.