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:
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:
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 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
für eine Sprache zu definieren, die bereits einen perfekt integrierten bool
-Typ hat. 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
.)
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 .
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;)
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.
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.
Tags und Links c++ windows type-conversion winapi boolean