unique_ptr <0 ODER was macht weniger als der Operator?


9

Ich habe es mit Code zu tun, der nicht von mir geschrieben wurde. Ich habe diese Aussage:

// p is type of std::unique_ptr<uint8_t[]>
if (p < 0) { /* throw an exception */ }

Was bedeutet p < 0das in diesem Zusammenhang?
Auf der Dokumentationsseite glaube ich, dass mein Fall ist 16) y < nullptr, wo 0ist nullptr.

Aber was macht es?


1
Basierend auf der Tatsache, dass in x64 für kanonische Zeiger im Kernelbereich das obere Bit gesetzt ist, könnte dies eine (dumme, fest codierte) Methode sein, um zu überprüfen, ob ein Zeiger zum Kernelraum gehört - wenn die folgende Antwort jedoch korrekt ist, dann nein .
Michael Chourdakis

1
In WINAPI p==-1ist ein ungültiges Handle. Da 2^64es sich um eine lächerlich große Zahl handelt, ist jeder vernünftige pimmer positiv. p<0Überprüft also , ob das WINAPI-Handle ungültig ist. Das ist kein guter Code.
ALX23z

@OP: Könnten Sie etwas klarstellen, in welchem ​​Kontext dieser Code verwendet wird? Wird es unter Linux oder Windows verwendet? Bezieht sich der Wert des Zeigers auf einen WINAPI-Code? Ich denke, wenn Sie das klargestellt haben, können die obigen Kommentare gute Antworten sein.
Walnuss

@ ALX23z Aber sollte ein WINAPI-Handle vom Typ sein uint8_t*(oder sogar ein Array von uint8_t)? Ich denke sie sind es void*, nicht wahr?
Walnuss

@walnut sie sind nicht void*sie haben Makro HANDLE_PTR oder etwas, das im Grunde long*iirc ist.
ALX23z

Antworten:


2

unique_ptr <0 ODER was macht weniger als der Operator?

Es entspricht der Überlastung (11) der Referenz operator<(const unique_ptr&, nullptr_t);. 0 konvertiert implizit in std::nullptr_t. Laut Dokumentation ist das Ergebnis std::less<unique_ptr<T,D>::pointer>()(x.get(), nullptr).

Das Ergebnis ist eine definierte Implementierung, die auf den meisten Systemen jedoch unbedingt falsch ist. Vermutlich auf einem exotischen System, auf dem null nicht die binäre Darstellung von 0 hat, könnte das Ergebnis wahr sein.

Ich glaube mein Fall ist 16)

(16) ist umgekehrt umgekehrt : 0 > unique_ptr. Das Ergebnis ist das gleiche.


Aber wird vom Compiler 0berücksichtigt nullptr? Ich denke, das wundert er sich. Das ergibt zumindest für mich keinen Sinn.
Geänderte Instanz

@alteredinstance 0 wird nicht "berücksichtigt" nullptr(oder hängt davon ab, was Sie unter Berücksichtigung verstehen). 0 konvertiert implizit in std::nullptr_t.
Eerorika

Das habe ich angenommen. Ich frage mich, ob es eine Dokumentation zur impliziten Konvertierung von 0in gibt nullptr, da ich nur die beiden gesehen habe, die mit booleschen Vergleichen kompatibel sind. Sie sind vergleichbar, aber ich hatte den Eindruck, dass sie nicht konvertierbar sind.
Geänderte Instanz

@alteredinstance Die Konvertierung erfolgt nicht umgekehrt. int x = nullptrist schlecht geformt.
Eerorika

2
@alteredinstance std::nullptr_twurde so konzipiert, dass es mit jeder Nullzeigerkonstante verwendet werden kann. nicht nur nullptr. 0 (wie auch 0L zum Beispiel) sind Nullzeigerkonstanten, daher ist beabsichtigt, dass sie zum Erstellen von a verwendet werden können std::nullptr_t.
Eerorika

2

Stellen Sie sicher, dass operator <irgendwo in Ihrer Codebasis keine Überlastung vorliegt. Das scheint der einzige Weg zu sein, wie es sein (p < 0)könnte true.

Beispiel:

bool operator< (const std::unique_ptr<uint8_t[]>&, int) { return true; }

int main() {
    std::unique_ptr<uint8_t[]> p;
    std::cout << (p < 0) << std::endl;
}

Drucke:

1

Live-Demo

Andernfalls wird, wie andere gesagt haben, 0implizit in konvertiert std::nullptr_t, wodurch die bool operator<(const unique_ptr<T, D>& x, nullptr_t)Überladung ausgewählt wird, die aufgerufen wird und std::less(p, 0)die zurückkehrt false(selbst unter Windows mit einem -1Zeigerwert).


Es muss nicht unbedingt zurückkehren false. Es ist entweder implementierungsdefiniert oder nicht spezifiziert (ich bin nicht sicher). Aber ich stimme zu, dass es wahrscheinlich falsebei den meisten (allen?) Implementierungen zurückkehren wird. Siehe auch Antwort von @eerorika
Walnuss

0

Dieser Ausdruck stimmt mit diesem Vorlagenoperator überein (0 wird konvertiert in nullptr):

template <class T, class D>
bool operator<(const unique_ptr<T, D>& x, nullptr_t);

Dies gibt zurück, std::less<unique_ptr<T,D>::pointer>()(p.get(), nullptr)was immer falsch ist (wie std::lesses ein strenger Ordnungsfunktor ist) ( Demo ).


Es kehrt nicht immer zurück false. Ob dies der Fall ist, ist entweder implementierungsdefiniert oder nicht spezifiziert. Bei den falsemeisten (allen?) Aktuellen Implementierungen wird es jedoch wahrscheinlich immer wieder angezeigt.
Walnuss

@walnut Sofern in einer Frage nicht explizit nach den Aussagen des Standards gefragt wird ( z. B. über das Tag für Sprachanwälte ), versuche ich, diese aus praktischer Sicht zu beantworten. Alle praktischen Umsetzung der std::lessRückgabe false.
YSC

Das ist in Ordnung, ich fand Ihre Argumentation (" da std :: less ein strenger Ordnungsfunktor ist ") einfach nicht überzeugend. Es kann eine strenge Bestellung sein, ohne zurückzukehren false. Der praktische Grund wäre, dass der Nullzeigerwert durch die niedrigstmögliche Adresse oder etwas in dieser Richtung dargestellt wird.
Walnuss
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.