Reihenfolge der booleschen Werte

Lesezeit: 5 Minuten

Benutzer-Avatar
Tom

Unter C++ bzw <stdbool.h> von C99, wie ist der Kleiner-als-Operator < für boolesche Werte definiert?

Erklären Sie alternativ das Verhalten dieses Codes:

#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stdio.h>

int main() {
    bool b = -1;
    if(b < true) {
        printf("b < true\n");
    }
    if(b < false) {
        printf("b < false\n");
    }
    if(true < false) {
        printf("true < false\n");
    }
    if(false < true) {
        printf("false < true\n");
    }
}

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

Benutzer-Avatar
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

Benutzer-Avatar
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.

Als weiteres Experiment der folgende Code

#include <iostream>

int main()
{
std::cout<< (((bool)1) == true) << "\n";
std::cout<< (((bool)2) == true) << "\n";
std::cout<< (((bool)0) == false) << "\n";
std::cout<< (((bool)1) == false) << "\n";
  return 0;
}

druckt 1 1 1 0

Also ist jeder Wert ungleich Null “wahr”.

1245150cookie-checkReihenfolge der booleschen Werte

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy