Ist NULL in C erforderlich/definiert als Null?

Lesezeit: 3 Minuten

Benutzeravatar von willhf
willhf

NULL scheint in meinen GCC-Testprogrammen Null zu sein, aber Wikipedia sagt das NULL muss nur auf einen nicht adressierbaren Speicher zeigen.

Machen irgendwelche Compiler NULL nicht null? Bin gespannt ob if (ptr == NULL) ist eine bessere Praxis als if (!ptr).

Benutzeravatar von Matteo Italia
Matteo Italien

NULL ist garantiert null, vielleicht gecastet (void *)1.

C99, §6.3.2.3, ¶3

Ein ganzzahliger konstanter Ausdruck mit dem Wert 0oder ein solcher Ausdruck, der in einen Typ umgewandelt wird
void *wird als Nullzeigerkonstante bezeichnet. (55) Wenn eine Nullzeigerkonstante in einen Zeigertyp konvertiert wird, ist der resultierende Zeiger, der als Nullzeiger bezeichnet wird, garantiert ungleich mit einem Zeiger auf ein Objekt oder eine Funktion.

Und Note 55 sagt:

55) Das Makro NULL ist definiert in <stddef.h> (und andere Header) als Nullzeigerkonstante.

Beachten Sie, dass der Wert, den Sie zum Zuweisen/Vergleichen von Nullzeigern verwenden, aufgrund der Formulierung der Regeln für Nullzeiger garantiert Null ist, aber das tatsächlich im Zeiger gespeicherte Bitmuster kann alles andere sein (aber AFAIK nur wenige sehr Esoterische Plattformen nutzten diese Tatsache aus, und dies sollte sowieso kein Problem darstellen, da Sie sich mit dem zugrunde liegenden Bitmuster befassen sollten, um es zu “sehen”. UB-Land sowieso).


Was den Standard betrifft, sind die beiden Formen also gleichwertig (!ptr ist äquivalent zu ptr==0 aufgrund §6.5.3.3 Abs. 5, und ptr==0 ist äquivalent zu ptr==NULL); if(!ptr) ist auch ziemlich idiomatisch.

Davon abgesehen schreibe ich normalerweise explizit if(ptr==NULL) Anstatt von if(!ptr) um es besonders deutlich zu machen, dass ich anstelle eines booleschen Werts einen Zeiger auf Nichtigkeit überprüfe.


  1. Beachten Sie, dass in C++ die void * Cast kann aufgrund der strengeren impliziten Casting-Regeln, die die Verwendung solcher machen würden, nicht vorhanden sein NULL umständlich (Sie müssten es jedes Mal explizit in den Typ des verglichenen Zeigers konvertieren).

  • Die Bytes in einem Nullzeiger müssen jedoch nicht Nullen sein.

    – Aschepler

    27. November 2011 um 19:57 Uhr

  • @aschepler: und was habe ich in meiner Antwort geschrieben?

    – Matteo Italien

    27. November 2011 um 19:58 Uhr

  • Kommentar bezog sich auf eine ältere Revision. gute Antwort.

    – Aschepler

    27. November 2011 um 20:05 Uhr

  • Der wichtigste Punkt zum Mitnehmen: void *p; memset(&p, 0, sizeof p); macht nicht p a NULL Zeiger.

    – Simon Richter

    28. November 2011 um 12:37 Uhr


  • @SimonRichter: Tut es nicht Notwendig machen p ein Nullzeiger. (Das ist sehr wahrscheinlich auf den meisten Systemen der Fall, aber abhängig davon wird Ihr Code nicht portierbar.)

    – Keith Thompson

    30. November 2011 um 5:32 Uhr

Benutzeravatar von John Bode
Johannes Bode

Aus dem Sprachstandard:

6.3.2.3 Zeiger


3 Ein ganzzahliger konstanter Ausdruck mit dem Wert 0 oder ein solcher Ausdruck, der in einen Typ umgewandelt wird
void *heißt a Nullzeiger konstant.55) Wenn eine Nullzeigerkonstante in einen Zeigertyp konvertiert wird, wird der resultierende Zeiger, genannt a Null Zeigerwird garantiert ungleich mit einem Zeiger auf ein Objekt oder eine Funktion verglichen.

55) Das Makro NULL ist darin definiert <stddef.h> (und andere Header) als Nullzeigerkonstante; siehe 7.17.

Angesichts dieser Sprache ist das Makro NULL sollte zu einem nullwertigen Ausdruck auswerten (entweder ein nicht ergänztes Literal 0ein Ausdruck wie (void *) 0, oder ein anderes Makro oder Ausdruck, der letztendlich 0 ergibt). Die Ausdrücke ptr == NULL und !ptr sollte gleichwertig sein. Die zweite Form ist eher idiomatischer C-Code.

Beachten Sie, dass der Nullzeiger Wert muss nicht 0 sein. Die zugrunde liegende Implementierung kann jeden beliebigen Wert verwenden, um einen Nullzeiger darzustellen. Was Ihren Quellcode betrifft, stellt ein nullwertiger Zeigerausdruck jedoch einen Nullzeiger dar.

In der Praxis ist es dasselbe, aber NULL ist anders als Null. Da Null bedeutet, dass es einen Wert gibt, und NULL bedeutet, dass es keinen gibt. Theoretisch sind sie also unterschiedlich, NULL hat eine andere Bedeutung und in einigen Fällen sollte dieser Unterschied von Nutzen sein.

  • Nah dran, aber nicht ganz genau. 0 ist ein Wert vom Typ int. NULL ist ein Wert vom Typ Zeiger. (Auch das ist ungenau; NULL ist ein Makro, das zu a erweitert wird Nullzeiger konstantwas a ergibt Null Zeiger bei Umwandlung in einen Zeigertyp.)

    – Keith Thompson

    30. November 2011 um 15:52 Uhr

in der Praxis nein, !ptr ist richtig

1408910cookie-checkIst NULL in C erforderlich/definiert als Null?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy