unique_ptr <0 O cosa fa meno dell'operatore?


9

Ho a che fare con un codice che non è stato scritto da me. Ho questa affermazione:

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

Quindi cosa p < 0significa in questo contesto?
Sulla pagina di documentazione , credo che il mio caso è 16) y < nullptr, dove 0è nullptr.

Ma che cosa fa?


1
In base al fatto che, in x64, i puntatori canonici nell'intervallo del kernel hanno il bit superiore impostato, potrebbe essere un modo (stupido codificato) di verificare se un puntatore appartiene allo spazio del kernel - se la risposta qui sotto è corretta, allora no .
Michael Chourdakis,

1
In WINAPI p==-1è un handle non valido. Dal momento che 2^64è un numero ridicolmente enorme ogni ragionevole pè sempre positivo. Quindi p<0controlla l'handle non valido di WINAPI. Questo non è un buon codice.
ALX23z,

@OP: Potresti chiarire un po 'in quale contesto viene utilizzato questo codice? È usato su Linux o Windows? Il valore del puntatore è correlato ad un codice WINAPI? Penso che se lo chiarissi, i commenti sopra potrebbero essere buone risposte.
noce

@ ALX23z Ma un handle WINAPI dovrebbe essere di tipo uint8_t*(o addirittura array di uint8_t)? Penso che lo siano void*, vero?
noce

@walnut non lo void*sono hanno macro HANDLE_PTR o qualcosa che è fondamentalmente long*iirc.
ALX23z,

Risposte:


2

unique_ptr <0 O cosa fa meno dell'operatore?

Corrisponde al sovraccarico (11) su cppreference operator<(const unique_ptr&, nullptr_t);. 0 si converte implicitamente in std::nullptr_t. Come da documentazione, il risultato è std::less<unique_ptr<T,D>::pointer>()(x.get(), nullptr).

Il risultato è definito dall'implementazione, ma incondizionatamente falso sulla maggior parte dei sistemi. Presumibilmente su un sistema esotico in cui null non ha la rappresentazione binaria di 0, il risultato potrebbe essere vero.

Credo che il mio caso sia 16)

(16) è lo stesso viceversa: 0 > unique_ptr. Il risultato è lo stesso


Ma è 0considerato nullptrdal compilatore? Penso che sia quello che si sta chiedendo. Neanche per me ha senso.
alteredinstance

@alteredinstance 0 non è "considerato" nullptr(o dipende da cosa intendi per considerazione). 0 si converte implicitamente in std::nullptr_t.
Eerorika,

Questo è quello che ho assunto. Mi chiedo se ci sia documentazione sulla conversione implicita di 0a nullptr, dal momento che ho visto solo i due compatibili con confronti booleani. Sono comparabili, ma avevo l'impressione che non fossero convertibili.
alteredinstance

@alteredinstance La conversione non avviene al contrario. int x = nullptrè mal formato.
Eerorika,

2
@alteredinstance è std::nullptr_tstato progettato per essere utilizzabile con qualsiasi costante puntatore null; non solo nullptr. 0 (così come 0L per esempio) sono costanti puntatore null, quindi è intenzione che possano essere usate per creare un std::nullptr_t.
Eerorika,

2

Verifica che operator <non sia sovraccarico da qualche parte nella tua base di codice. Questo sembra essere l'unico modo in cui (p < 0)potrebbe essere true.

Esempio:

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;
}

stampe:

1

dimostrazione dal vivo

Altrimenti, come altri hanno già detto, si 0converte implicitamente in std::nullptr_t, che selezionerebbe il bool operator<(const unique_ptr<T, D>& x, nullptr_t)sovraccarico che chiamerebbe std::less(p, 0)che ritornerebbe false(anche su Windows con un -1valore puntatore).


Non ritorna necessariamentefalse . È definito dall'implementazione o non specificato (non ne sono sicuro.) Ma sono d'accordo che probabilmente tornerà falsesulla maggior parte (tutte?) Delle implementazioni. Vedi anche la risposta di @eerorika
noce

0

Questa espressione corrisponde a questo operatore modello (0 convertito in nullptr):

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

Questo restituisce std::less<unique_ptr<T,D>::pointer>()(p.get(), nullptr)che è sempre falso (come std::lessè un funzione di ordine rigoroso) ( demo ).


Non sempre ritorna false. Se lo fa è definito dall'implementazione o non specificato. Probabilmente restituisce sempre falsecomunque sulla maggior parte (tutte?) Le implementazioni attuali.
noce

@walnut A meno che una domanda non faccia esplicitamente una domanda su ciò che dice lo Standard (attraverso il tag language-lawyer per esempio), provo a rispondere da un punto di vista pratico. Tutta l'implementazione pratica del std::lessritorno false.
YSC

Va bene, non ho trovato convincente il tuo ragionamento (" come std :: less è un funzione di ordine rigoroso "). Può essere un ordine rigoroso senza tornare false. La ragione pratica sarebbe che il valore del puntatore zero è rappresentato dall'indirizzo più basso possibile o qualcosa lungo quelle linee.
noce
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.