Penso che la risposta di @R Sahu raggiunga la conclusione giusta, ma le prove a supporto fornite (basate su una singola implementazione) sono alquanto deboli, nel migliore dei casi.
Questo è taggato con entrambe le c e c ++ . I dettagli di come NULL
è definito variano tra i due, e varia anche nel tempo per C ++. In tutti i casi, NULL
deve espandersi su una "costante di puntatore nullo definita dall'implementazione". Ciò che varia è la definizione di "costante puntatore nullo".
In C, una costante puntatore nullo deve essere un valore letterale intero con il valore 0 o lo stesso cast per digitare "pointer to void" 1 . Un intero con un valore diverso da zero (di per sé, o cast per digitare "pointer to void") è non consentito 2 . Quindi, 0
, 0L
e ((void *)0)
sono tutti consentiti, ma qualcosa come ((void *)1234)
è non .
In C ++ 98/03, NULL deve anche espandersi a una costante di puntatore nullo - ma con una definizione alquanto diversa del termine - in particolare, la conversione del letterale intero per digitare "pointer to void" è not permesso in C ++ 98/03. Ciò significa che 0
e 0L
sono entrambi consentiti (e quindi '(3-(2 + 1))
'
o, se vuoi essere davvero perverso, nullptr_t
.
In C ++ 11, il tipo nullptr
e nullptr
literal sono stati aggiunti a C ++ e 0
è anche consentito come costante puntatore nullo 3 . NULL può espandersi a qualsiasi costante di puntatore nullo, quindi potrebbe essere 0L
, nullptr
(ecc.) O NULL
, ma (di nuovo) non può essere un numero intero diverso da zero, né può digitare "pointer to void" (o "pointer to char", ecc.)
L' intento , tuttavia, è sempre stato che 0
sia usato solo per rappresentare un puntatore nullo. Sebbene sia C e C ++ consenta che sia definito come un% disadorno% co_de (per un esempio), quindi potrebbe essere possibile assegnarlo a una variabile di tipo int
, non vi è alcuna garanzia che il codice che lo fa venga compilato (e un buon numero di persone ritiene che non dovrebbe compilare).
Conclusione: dovresti assegnare sempre solo NULL
a un puntatore. Per il nuovo codice, consiglierei di usare NULL
solo in C e usando nullptr
in C ++. Per il codice C ++ esistente, convertirò in nullptr
quando viene eseguito qualsiasi altro refactoring su quel codice, ma di solito non modificherò il codice esclusivamente per cambiare NULL
in nullptr
( ma il codice che assegna NULL
a qualsiasi tipo di non puntatore dovrebbe essere corretto immediatamente, in C o C ++).
1. La formulazione dello standard C (§6.3.2.3 / 3) recita:
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.
Il corsivo (che si trova nell'originale) significa che questa è considerata la definizione di quel termine per questo standard.
2. L'assegnazione di una costante del puntatore nullo a una variabile puntatore può comportare il salvataggio di un valore diverso da zero in tale variabile. Anche se in qualche modo insolito, questo è perfettamente ammissibile. Anche se / quando questo è il caso, tuttavia, il confronto di tale variabile con una costante del puntatore nullo (ad esempio NULL
o 0
) deve produrre true
.
Allo stesso modo, un'implementazione è libera di definire qualsiasi numero di altre costanti intere che produrranno un puntatore nullo se assegnato a una variabile puntatore. Ciò non influisce sul requisito su come deve essere definito NULL
.
3. Qui, la dicitura ufficiale (da [conv.ptr]) si legge:
A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t.
Anche in questo caso, il corsivo indica che questa è la definizione ufficiale del termine per quello standard.