Wie konvertiere ich idiomatisch ein BOOL in ein bool?

8

Der Header <windows.h> kommt mit einem eigenen BOOL -Typ. Wenn ich auf die Implementierung schaue, scheint FALSE nur ein Makro für 0 zu sein, und TRUE ist nur ein Makro für 1 , aber ich bin nicht sicher, ob das angegeben ist.

Was ist der idiomatische Weg, ein BOOL in ein bool umzuwandeln? Ich kann mir viele Möglichkeiten vorstellen:

%Vor%     
fredoverflow 29.08.2013, 19:55
quelle

5 Antworten

6

Es ist keine explizite Konvertierung erforderlich:

%Vor%

Die implizite Konvertierung eines numerischen Typs in bool ergibt false für einen Wert von 0 und true für einen Wert ungleich Null.

Sie haben uns übrigens gesagt, wie <windows.h> FALSE und TRUE definiert. Wie definiert es BOOL ? (Von Ihrem Kommentar ist es typedef int BOOL; )

Aber einige Compiler warnen möglicherweise vor dieser impliziten Konvertierung, obwohl es sich um einen vollkommen gültigen Code handelt. Compiler können jederzeit über alles, was sie möchten, warnen, einschließlich der hässlichen Schriftart, mit der Sie Ihren Code geschrieben haben. g ++ zum Beispiel klagen nicht über die Konvertierung, auch nicht mit:

%Vor%

Aber nach diesem Online-Visual C ++ - Compiler erzeugt VC ++ eine Warnung:

%Vor%

Auch bei static_cast wird immer noch die Warnung ausgegeben.

Sie können die Warnung vermeiden, indem Sie !!x oder x ? true : false verwenden. Aber ich bin mir nicht sicher, ob die Heilung besser ist als die Krankheit.

Der einfache und korrekte Weg, dies zu tun, besteht einfach darin, den Wert zuzuweisen und sich auf die implizite Umwandlung zu verlassen, um das Richtige zu tun (wird es).

Wenn Sie eine zusätzliche Anforderung haben, Compilerwarnungen zu vermeiden, wird dies eher eine Frage zu Visual C ++ als zur C ++ - Sprache. Es kann auch eine Möglichkeit geben, bestimmte Warnungen zu unterdrücken, ohne die Quelle zu ändern - obwohl das Risiko besteht, dass dieselben Warnungen verloren gehen, wenn sie tatsächlich sinnvoll sind. In einem Kommentar schlägt Dieter Lücking vor:

%Vor%

Aber das sieht so aus, als müsste die Quelle noch modifiziert werden. Vielleicht gibt es etwas Äquivalentes, das nicht.

Noch eine Sache: Da BOOL wirklich den Typ int hat, ist diese vorgeschlagene Lösung:

%Vor%

entspricht nicht den anderen. Jedes int ungleich null wird als wahr behandelt, aber nur der Wert 1 ist gleich bis TRUE . Das obige Beispiel setzt c auf false wenn x == 2 , während if (x) es immer noch als eine wahre Bedingung behandelt. Vergleichen Sie boolesche Werte für Gleichheit niemals mit true oder TRUE . (Vergleicht man sie mit false oder FALSE ist sicherer, aber immer noch nicht notwendig; dafür steht der Operator ! .)

Dies alles setzt voraus, dass wenn Sie einen Wert vom Typ BOOL haben, Sie nur darauf achten, ob es falsish oder truthy (Null oder nicht Null) ist. Leider ist dies möglicherweise nicht immer der Fall. Wie die Ben Voight-Antwort zeigt, enthält Microsofts API mindestens eine Funktion, GetMessage , die ein BOOL -Ergebnis zurückgibt, das nicht ist, einen einfachen booleschen Wert. In solch einem schrecklichen Fall ist die Konvertierung von BOOL nach bool nicht geeignet, wenn Sie zwischen den mehreren Werten ungleich Null unterscheiden müssen.

Letztendlich mache ich Microsoft dafür verantwortlich, einen Typ BOOL für eine Sprache zu definieren, die bereits einen perfekt integrierten bool -Typ hat. Eigentlich ist das nicht ganz fair; Es wird in APIs verwendet, auf die sowohl von C als auch von C ++ zugegriffen werden muss. Microsofts Definition von BOOL geht wahrscheinlich auf ihre C-Implementierung zurück, wo sie sinnvoll ist - zumindest vor C99, die Microsoft immer noch nicht unterstützt. (Ich weiß nicht, ob Microsofts C-Compiler _Bool unterstützt. Selbst wenn dies der Fall ist, hat _Bool einige semantische Unterschiede von int , und die Änderung der Definition von BOOL könnte Code sprengen - insbesondere Code, der verwendet GetMessage .)

    
Keith Thompson 29.08.2013, 20:00
quelle
1

Ich benutze ein Makro:

%Vor%

IMO, macht meinen Code lesbarer.

BEARBEITET: Ein Kommentator hat meine Verwendung von Unterstrichen im Makronamen in Frage gestellt. Um dies anzugehen, hier ist eine neue Version, die immer noch generisch ist und immer noch den gleichen Namen _bool verwendet, aber konform ist, nach dies .

%Vor%     
avo 30.08.2013 05:35
quelle
0

Es ist schwer zu sagen, wie würde der win32-Programmierer es tun, aber IMHO sollte es getan werden:

%Vor%

oder

%Vor%

Ich denke, es ist eine schlechte Übung, auf Makros (oder irgendwelche anderen vordefinierten Sachen) zu reagieren Beständigkeit.

Eines Tages kann TRUE 0 werden und FALSE 1;)

    
Michał Walenciak 29.08.2013 20:08
quelle
0

Es gibt keinen sicheren Weg, dies zu tun, weil Win32 BOOL mehr als zwei hat Werte .

    
Ben Voigt 29.08.2013 20:16
quelle
0

Dies ist eine Frage der Meinung, aber ich denke, es gibt objektive Argumente für die verschiedenen Optionen.

Die beste Wahl ist:

%Vor%

Dies macht die Absicht für den Leser sehr klar, verlässt sich nicht auf implizite Konvertierungen und macht deutlich, dass mehr vor sich geht als eine einfache Zuweisung.

Die zweitbeste Wahl ist:

%Vor%

Aber dem gelegentlichen Leser kann das wie eine Tautologie erscheinen.

Ich versuche, implizite Conversions in Zuweisungen zu vermeiden, da es eine überraschende Fehlerquelle ist, eine falsche Conversion zu erhalten. Selbst wenn ich weiß , dass die implizite Konvertierung das Richtige tut, tendiere ich dazu, dies explizit zu tun, was für jemanden, der den Code in der Zukunft liest, hilfreich sein kann. Wenn Sie explizit angeben, können Sie auch die Conversion-Warnungen aktivieren, damit Sie die anderen impliziten Conversions erkennen, die Sie nicht wussten (ab).

Die Alternativen haben alle ernstere Nachteile.

%Vor%

Das ist wie ein quadratischer Pflock in ein rundes Loch zu hämmern. Es ist eleganter, einen Ausdruck zu schreiben, der natürlich den richtigen Typ zurückgibt.

%Vor%

Es ist generell eine schlechte Idee, mit TRUE zu vergleichen, da andere Werte ungleich Null in false konvertiert würden, was fast sicher ein Fehler ist.

%Vor%

Zu schlau im Vergleich zu den Alternativen, die genau das ausdrücken, was Sie meinen. (Ich bin schuldig, dies in der Vergangenheit getan zu haben.)

%Vor%

Die Leistungswarnung, die MSVC ++ bei der rein impliziten Konvertierung aussendet, scheint gerecht zu sein. Der Compiler muss zusätzlichen Code generieren, um ein int in ein bool zu konvertieren. Die bloße Aufgabe gibt wenig Hinweis auf diese zusätzliche Arbeit. Wenn es in einer engen Schleife ist, könnte es dich interessieren. (Zugegeben, die Leistungswarnung für die Option static_cast scheint ungeheuerlich, aber wir haben das schon als weniger elegant ausgemacht.)

Die Ausdrücke d und b drücken deutlich die Absicht aus und machen deutlich, dass hier mehr vor sich geht als eine direkte Aufgabe.

    
Adrian McCarthy 15.11.2016 22:08
quelle