Konvertierung von Bool nach Int


130

Wie portabel ist diese Konvertierung? Kann ich sicher sein, dass beide Behauptungen zutreffen?

int x = 4<5;
assert(x==1);

x = 4>5;
assert(x==0);

Fragen Sie nicht warum. Ich weiß, dass es hässlich ist. Danke dir.


Warum ändern Sie nicht den ersten Ausdruck? Du kannst schreiben assert(x!=0). Selbst wenn bool (true) portable in int (1) konvertiert, haben die Asserts "nicht false" einen besser lesbaren Ausdruck.
Harper

1
Warum nicht: assert( 4 < 5);undassert(!( 4 > 5));
Martin York

4
@harper: Die Verwendung des erforderlichen Werts eines Vergleichsausdrucks ist durchaus sinnvoll.
R .. GitHub STOP HELPING ICE

@ R._ Wenn die Frage ist, ob die Konvertierung von Bool zu Int ein vernünftiges Ergebnis liefert, würde ich mich nicht darauf verlassen. Wenn der Autor Zweifel hat, dass diese Anforderung erfüllt ist, kann der Leser das gleiche Problem bekommen. Insbesondere, weil der Wert von x nicht die zu überprüfende Bedingung ist, sondern nur ein Zwischenergebnis.
Harper

3
Ich würde wahrscheinlich schreiben, (4 < 5) ? 1 : 0wenn ich wirklich einen Booleschen Wert in 0 oder 1 konvertieren muss. Ein guter Compiler wird wahrscheinlich denselben Maschinencode erzeugen und es ist für einen menschlichen Leser klarer.
ollb

Antworten:


204
int x = 4<5;

Komplett tragbar. Standardkonform. boolzur intKonvertierung ist implizit!

§4.7 / 4 aus dem C ++ Standard sagt (Integral Conversion )

Wenn der Quelltyp bool ist, wird der Wert falsein Null und der Wert truein Eins konvertiert .


Wie bei C, soweit ich weiß , gibt es keine boolin C (vor 1999) So boolzu intKonvertierung relevant in C ++ nur. In C, 4<5auswertet , um intWert, in diesem Fall der Wert ist 1, 4>5 würde zu evaluieren 0.

EDIT: Jens im Kommentar sagte, C99 hat _BoolTyp. boolist ein in der stdbool.hHeader-Datei definiertes Makro . trueund falsesind auch Makro definiert in stdbool.h.

§7.16 von C99 sagt,

Das Makro wird boolzu _Bool erweitert.

[..] truedie sich zur Ganzzahlkonstante erweitert 1, falsedie sich zur Ganzzahlkonstante erweitert 0, [..]


3
boolStellen Sie sicher, dass es C seit 1999 gibt. Verwenden Sie einfach den Header "stdbool.h" und dieser sollte enthalten sein.
Jens Gustedt

1
In der Tat habe ich es auf mehreren Compilern überprüft und es scheint portabel zu sein.
Bild

8
Unabhängig von der Version der C-Sprache und der Verfügbarkeit von bool/ _Booltype produzieren Vergleichsoperatoren in C intnicht bool. Dh auch in C99 produzieren relationale Operatoren noch int.
Am

51

Sie haben Ihre Frage [C] und [C ++] gleichzeitig markiert. Die Ergebnisse sind zwischen den Sprachen konsistent, aber die Struktur der Antwort ist für jede dieser Sprachen unterschiedlich.

In der C-Sprache haben Ihre Beispiele keinerlei Beziehung boolzu (dies gilt auch für C99). In der Sprache C erzeugen relationale Operatoren keine boolErgebnisse. Beide 4 > 5und 4 < 5sind Ausdrücke, die Ergebnisse vom Typ intmit Werten 0oder erzeugen 1. In Ihren Beispielen in C findet also keinerlei "Bool to Int-Konvertierung" statt.

In C ++ erzeugen relationale Operatoren tatsächlich boolErgebnisse. boolWerte können in intTyp konvertiert werden, wobei truekonvertiert in 1und falsekonvertiert in 0. Dies wird durch die Sprache garantiert.

Die PS C-Sprache hat auch einen dedizierten booleschen Typ _Bool(Makro-Alias ​​als bool), und die integralen Konvertierungsregeln sind im Wesentlichen dieselben wie in C ++. Dies ist jedoch für Ihre spezifischen Beispiele in C nicht relevant. Auch hier liefern Vergleichsoperatoren in C unabhängig von der Version der Sprachspezifikation immer int(nicht bool) Ergebnisse.


2
Das ist richtig, es gibt keinen Bool in K & R C. Ich habe meine Frage als C99 neu markiert.
Bild

@ pic11: Es war nicht nötig, irgendetwas neu zu markieren. Es hat nichts mit K & R oder einem anderen C zu tun. Obwohl es boolin C99 gibt, produzieren die Vergleichsoperatoren immer noch intin C99, nicht bool. Wenn es sich also speziell um relationale Operatoren handelt, an denen Sie interessiert sind (wie in Ihren Beispielen), hat das Problem immer noch nichts damit zu tun bool.
Am

Jetzt habe ich es verstanden. Das Ergebnis des Beziehungsoperators kann implizit in int konvertiert werden. Dies gilt für C, C99 und C ++. Erneut tariert.
Bild

3
@ pic11: Nein, du verstehst es nicht. In C, einschließlich C99, ist das Ergebnis eines Vergleichsoperators ein int, kein a bool. Es findet keine Konvertierung statt.
R .. GitHub STOP HELPING ICE

Gibt es eine standardkonforme Methode, mit der eine Sprache einen Typ haben kann, der sich verhält bool, aber nicht zulässt, dass seine Adresse verwendet wird? Viele eingebettete Systeme verwenden solche Typen (häufig unter Verwendung der Kennung deklariert bit). Bei beispielsweise einem PIC mit mittlerer Reichweite if (bitVar1) bitVar2=1;wären zwei Anweisungen; Die optimale Codierung für if (byteVar1) byteVar2=1;wäre mindestens vier (bei vielen Compilern wahrscheinlich fünf). Solche Typen können somit eine erhebliche Leistungssteigerung bieten.
Supercat

17

In Abschnitt 6.5.8.6 des C-Standards heißt es:

Jeder der Operatoren <(kleiner als),> (größer als), <= (kleiner als oder gleich) und> = (größer als oder gleich) muss 1 ergeben, wenn die angegebene Beziehung wahr ist, und 0, wenn dies der Fall ist false.) Das Ergebnis hat den Typ int.


Danke für den Hinweis. Es scheint, dass aus historischen Gründen wahr == 1 ist.
Bild

2

Es scheint kein Problem zu geben, da die Umwandlung von int to bool implizit erfolgt. Dies funktioniert in Microsoft Visual C ++, GCC und Intel C ++ Compiler. Kein Problem in C oder C ++.


2
"In einigen Fällen funktioniert es" ist keine gute Möglichkeit, die Richtigkeit zu überprüfen, insbesondere bei nicht angegebenen Versionen dieser Tools. Ich bevorzuge den Ansatz in den anderen Antworten; Sie können nicht garantieren, dass eine bestimmte Implementierung korrekt ist, aber sie können garantieren, was eine korrekte Implementierung bewirkt.
Matthew Read
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.