style - size of nullptr c++




Ist nullptr falsch? (2)

Ja, aber Sie sollten diese Tatsache vermeiden.

Der Vergleich von Zeigern mit false oder mit 0 ist ein häufiger Fehler bei der C / C ++ - Codierung. Ich schlage vor, dass Sie es vermeiden . Wenn Sie auf Null prüfen möchten, verwenden Sie:

if (x == nullptr) { /* ... */}

eher, als

if (!x) { /* ... */}

oder

if (not x) { /* ... */}

Die zweite Variante bringt dem Leser ein weiteres bisschen Verwirrung: Was ist x ? Ist es ein Boolescher? Ein einfacher Wert (zB eine ganze Zahl)? Ein Zeiger? Ein optionales? Auch wenn x einen aussagekräftigen Namen hat, hilft es Ihnen nicht viel: if (!network_connection) ... es könnte immer noch eine komplexe Struktur sein, die in eine Ganzzahl oder einen Booleschen if (!network_connection) konvertiert werden kann, es könnte ein Boolescher Indikator dafür sein, ob eine Verbindung besteht Dies kann ein Zeiger, ein Wert oder ein optionaler Wert sein. Oder etwas anderes.

nullptr auch daran, dass nullptr falsch ist. nullptr ist eine weitere Information, die Sie im hinteren Teil Ihres Gehirns speichern müssen, um den Code, den Sie lesen, richtig zu dekodieren. Wir sind es vielleicht aus alten Zeiten gewöhnt oder lesen den Code anderer Leute - aber wenn wir es nicht wären, wäre es nicht offensichtlich gewesen, dass sich nullptr verhält. In gewisser Hinsicht ist es nicht unähnlich zu anderen undurchsichtigen Garantien, wie zum Beispiel, dass der Wert am Index 0 eines leeren std::string garantiert \0 . Lassen Sie Ihren Code nur dann nicht auf dieses Zeug vertrauen, wenn Sie es unbedingt müssen.

PS: Heutzutage wird für Nullzeiger viel weniger verwendet. Sie können erzwingen, dass der Zeiger niemals null ist, wenn dies nicht erforderlich ist. Sie können Referenzen anstelle von Zeigern verwenden. und Sie können std::optional<T> , um entweder ein T oder "kein T" zurückzugeben. Vielleicht könnten Sie es einfach vermeiden, nullptr insgesamt zu erwähnen.

Ist nullptr als boolescher Ausdruck verwendet oder explizit oder implizit in einen booleschen Ausdruck umgewandelt durchgehend falsch? Ist diese Implementierung in der Norm definiert oder spezifiziert?

Ich habe einen Code zum Testen geschrieben, bin mir aber nicht sicher, ob er diese Eigenschaft vollständig testet. Ich konnte keine existierende SO-Antwort finden, die speziell darüber sprach. cppreference dies nicht aus dem, was ich sehe.

if (nullptr) {
    ;
} else {
    std::cout << "Evaluates to false implicitly\n";
}

if (!nullptr) {
    std::cout << "Evaluates to false if operated on\n";
}

if (!(bool)(nullptr)) {
    std::cout << "Evaluates to false if explicitly cast to bool\n";
}

Erwartet und aktuell:

Evaluates to false implicitly
Evaluates to false if operated on
Evaluates to false if explicitly cast to bool

Das Ergebnis Ihres Codes ist garantiert, [dcl.init]/17.8

Wenn es sich bei der Initialisierung um eine Direktinitialisierung handelt, lautet der Quellentyp std​::​nullptr_t und der std​::​nullptr_t ist bool . Der Anfangswert des zu initialisierenden Objekts ist false .

Das heißt, zur direkten Initialisierung kann ein bool Objekt von nullptr mit dem Ergebniswert false initialisiert werden. Dann wird für (bool)(nullptr) nullptr in bool mit dem Wert false konvertiert.

Bei Verwendung von nullptr als Bedingung von if oder dem Operanden von operator! , es wird als kontextbezogene Konvertierungen betrachtet ,

Die implizite Konvertierung wird ausgeführt, wenn die Deklaration bool t(e); ist wohlgeformt

Das heißt, sowohl if (nullptr) als auch !nullptr , wird nullptr in bool mit dem Wert false konvertiert.





nullptr