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.