2009-10-22 22 views
7

Nel seguente codice, qual è il vantaggio dell'uso di (!!p) anziché di (p != NULL)?Perché/Quando utilizzare (!! p) anziché (p! = NULL)

AClass *p = getInstanceOfAClass(); 
if(!!p) 
    // do something 
else 
    // do something without having valid pointer 
+22

Mi chiedo cosa c'è che non va con 'if (p)'. – GManNickG

+1

Assolutamente nulla. :) – Twisol

+3

Si dovrebbe sempre sospettare che gli operatori siano sovraccarichi. È possibile che '! P' o'! = 'Abbiano comportamenti speciali. – Kobi

risposta

9

Questa è una questione di stile, in effetti sono equivalenti. Vedi this very similar question per la discussione.

Il confronto IMO con il puntatore nullo è più chiaro.

3

Per quanto posso vedere, è solo un modo più breve per convertirlo in un valore booleano. Applica il! due volte, però, mentre p != NULL fa un confronto. Quindi immagino che il vantaggio sia solo un codice più breve, anche se più criptico se non si sa che cosa dovrebbe significare !!p.

11

È praticamente la stessa cosa, anche se considero lo !!p di cattivo stile e di solito indica che un programmatore sta cercando di essere intelligente.

+4

Se ti ci vuole un'ora per scrivere il codice intelligente, ci vorranno due per capirlo dopo poche settimane. – Twisol

+2

Sono pienamente d'accordo. Dovrebbe aver letto "cercando di essere intelligente e fallendo" – Wernsey

0

sono lo stesso, ma vi consiglio di usare

NULL != p 

È più leggibile.

+0

Questo non è altro che preferenze personali e stile. –

+4

La leggibilità di esso è discutibile. Personalmente, lo trovo * meno * leggibile, semplicemente perché non legge naturalmente. Di solito dico 'se p non è NULL' non 'se NULL non è p'. –

+3

Sì, ma impedisce alle persone di perdere un errato "p = NULL" mentre il compilatore preleva "NULL = p". – ChrisBD

-2

Do !! NON usare la doppia negazione. Un semplice argomento è che dal momento che C++ è un sottoinsieme inglese limitato e l'inglese non ha una doppia negazione, allora i diffusori inglesi avranno molte difficoltà ad analizzare cosa sta succedendo.

+1

Vedo cosa hai fatto lì ... – Twisol

+0

Tranne se hai anche preso lezioni di latino, allora la doppia negazione - a seconda del contesto - non si cancella, ma il significato della negazione è amplificato. – MP24

+2

Tranne quello! (C++ è un sottoinsieme limitato di inglese). – outis

-1

Non vi sono differenze nell'esempio riportato.

Tuttavia, il presupposto che ciò si applica a tutti i casi non è corretto. a = not not b non corrisponde a a = b, per quanto riguarda i tipi di numeri interi.

In C, 0 è falso. Tutto tranne 0 è vero. Ma not 0 è 1 e nient'altro. In C++, vero calchi di 1 come un intero, non solo per compatibilità all'indietro con C, ma perché 1 non è 0, e 1 è il valore più comune utilizzato per indicare vero in tipi C booleani, compreso il official C bool type e BOOL utilizzati in Win32.

Mentre per l'esempio di codice proposta, !!p è necessario in quanto il risultato viene colato in un bool per la valutazione della condizione if, che non esclude l'uso di !! per scopi di colata booleani di valori interi attesi. Personalmente in questo esempio, per massimizzare la probabilità che le modifiche di tipo e la semantica siano chiare, vorrei usare NULL != p o p != NULL per rendere assolutamente chiaro cosa si intende.

Questa tecnica è nota come idioma double-bang e this guy provides some good justifications.

+0

Queste giustificazioni non sono valide in questa istanza. –

+0

In questo contesto, in realtà se (p) e if (!! p) * sono * identici. Questo perché la condizione di "se" viene convertita in bool e testata, il che è esattamente ciò che !! finisce per fare. Rispondendo alla risposta, in C++ i ragazzi del kernel avrebbero potuto esprimere il loro valore a un bool. –

+0

"Mentre per l'esempio di codice fornito, !! p non è ovviamente necessario," forse dovrei renderlo più chiaro. –

7

io cosa commento originale di Gman dovrebbe essere la risposta accettata:

Mi chiedo cosa c'è di sbagliato con solo if (p)

Il punto è: nulla è sbagliato con esso, e questo dovrebbe essere il modo preferito. Innanzitutto, !!p è "troppo intelligente"; è anche completamente inutile e quindi negativo (nota: stiamo parlando di puntatori in una dichiarazione if qui, quindi il commento di Anacrolix, sebbene generalmente valido, non si applica qui!).

Lo stesso vale per p != NULL. Mentre questo è possibile, non è solo necessario. È più codice, è completamente ridondante codice e quindi peggiora il codice. La cosa più vera che Jeff Atwood ha mai detto è che "il miglior codice non è affatto codice". Evita la sintassi ridondante. Attenersi al minimo (che trasmette ancora il significato completo: if (p)è completato).

Infine, if (p) è probabilmente il modo più idiomatico per scrivere questo in C++. C++ si piega all'indietro per ottenere lo stesso comportamento per altri tipi nella lingua (ad esempio flussi di dati), al costo di alcune stranezze molto strane. La prossima versione dello standard introduce anche una nuova sintassi per ottenere questo comportamento nei tipi definiti dall'utente.

Per i puntatori, otteniamo lo stesso gratuitamente. Quindi usalo.

/EDIT: A proposito di chiarezza: sharptooth scrive che

IMO confrontando contro puntatore nullo è più chiaro.

Io sostengo che questo è oggettivamente sbagliato: if (p) è più chiaro. Non c'è modo che questa affermazione possa significare altro, né in questo contesto né in nessun altro, in C++.

+0

Seguo questo. se (p) fa tutto, è breve, è chiaro.(E alcuni potrebbero anche chiamare l'ulteriore vantaggio di non usare "NULL", poiché preferiscono "0") – stijn

+2

Preferisco prenotare se (x) per i tipi booleani, e se (x! = Nullptr/* o NULL * /) per i tipi di puntatore. In questo modo i controlli del puntatore risaltano nel codice e sono facili da cercare. – Bill

+0

"Non esiste alcun modo per cui questa affermazione possa significare qualcos'altro" - Non c'è anche alcun modo possibile che se (p! = NULL) possa significare qualsiasi cosa eccetto p non equivale a NULL, qualunque sia NULL. –