Verwenden Sie NULL oder 0 (Null) für Zeiger in C ++?


192

In den frühen Tagen von C ++, als es auf C geschraubt wurde, konnten Sie NULL nicht so verwenden, wie es definiert wurde (void*)0. Sie konnten keinem anderen Zeiger als NULL zuweisen void*, was es irgendwie nutzlos machte. Damals wurde akzeptiert, dass Sie 0(Null) für Nullzeiger verwendet haben.

Bis heute habe ich weiterhin Null als Nullzeiger verwendet, aber die um mich herum bestehen darauf, sie zu verwenden NULL. Ich persönlich sehe keinen Vorteil darin, einem NULLvorhandenen Wert einen Namen ( ) zu geben - und da ich auch gerne Zeiger als Wahrheitswerte teste:

if (p && !q)
  do_something();

Dann ist die Verwendung von Null sinnvoller (wie wenn Sie verwenden NULL, können Sie nicht logisch verwenden p && !q- Sie müssen explizit mit Null vergleichen NULL, es sei denn, Sie nehmen an , dass NULLNull ist. In diesem Fall warum verwenden NULL).

Gibt es einen objektiven Grund, Null gegenüber NULL zu bevorzugen (oder umgekehrt), oder ist alles nur eine persönliche Präferenz?

Bearbeiten: Ich sollte hinzufügen (und ursprünglich sagen), dass ich mit RAII und Ausnahmen selten Null / NULL-Zeiger verwende, aber manchmal braucht man sie immer noch.


9
Warten Sie, ist kein Nullzeiger erforderlich, um als falsch ausgewertet zu werden, unabhängig davon, ob null intern Null ist oder nicht?
Mooing Duck

Antworten:


185

Hier ist Stroustrups Sichtweise: C ++ - FAQ zu Stil und Technik

In C ++ ist die Definition von NULL0, daher gibt es nur einen ästhetischen Unterschied. Ich bevorzuge es, Makros zu vermeiden, deshalb verwende ich 0. Ein weiteres Problem NULList, dass die Leute manchmal fälschlicherweise glauben, dass es sich von 0 unterscheidet und / oder keine ganze Zahl ist. Im vorstandardisierten Code NULLwurde / wird manchmal etwas Ungeeignetes definiert und musste / muss daher vermieden werden. Das ist heutzutage weniger verbreitet.

Wenn Sie den Nullzeiger benennen müssen, rufen Sie ihn auf nullptr. So heißt es in C ++ 11. Dann nullptrwird ein Schlüsselwort sein.

Das heißt, schwitzen Sie nicht die kleinen Sachen.


7
Bjarne schrieb dies, bevor C ++ 0x anfing, an einem neuen Nulltyp zu arbeiten. Es wird der Fall sein, dass NULL für diesen Typ verwendet wird, wenn es für eine Plattform verfügbar ist, und ich denke, Sie werden eine C-Änderung im allgemeinen Konsens darüber sehen.
Richard Corden

122

Es gibt einige Argumente (von denen eines relativ neu ist), die meiner Meinung nach Bjarnes Standpunkt dazu widersprechen.

  1. Absichtserklärung

Mit NULLermöglicht Suchanfragen auf seine Verwendung und es zeigt auch , dass der Entwickler wollten ein verwenden NULLZeiger, unabhängig davon , ob sie vom Compiler wie interpretiert wird NULLoder nicht.

  1. Überladung von Zeiger und 'int' ist relativ selten

Das Beispiel, das jeder zitiert, ist:

void foo(int*);
void foo (int);

void bar() {
  foo (NULL);  // Calls 'foo(int)'
}

Zumindest meiner Meinung nach besteht das Problem mit dem oben Gesagten jedoch nicht darin, dass wir NULL für die Nullzeigerkonstante verwenden, sondern darin, dass wir Überladungen von 'foo' haben, die sehr unterschiedliche Arten von Argumenten annehmen. Der Parameter muss auch ein intsein, da jeder andere Typ zu einem mehrdeutigen Aufruf führt und daher eine hilfreiche Compiler-Warnung generiert.

  1. Analysetools können HEUTE helfen!

Selbst wenn C ++ 0x nicht vorhanden ist, stehen heute Tools zur Verfügung, die überprüfen, ob NULLsie für Zeiger und 0für integrale Typen verwendet werden.

  1. C ++ 11 wird einen neuen std::nullptr_tTyp haben.

Dies ist das neueste Argument in der Tabelle. Das Problem von 0und NULLwird für C ++ 0x aktiv angegangen, und Sie können garantieren, dass für jede bereitgestellte Implementierung NULLdas allererste, was sie tun, Folgendes ist:

#define NULL  nullptr

Für diejenigen , die verwendet werden, NULLstatt 0, wird die Änderung eine Verbesserung der Typsicherheit mit wenig oder gar keine Mühe - wenn alles , was es auch ein paar Fehler fangen können , wo sie verwendet haben NULLfür 0. Für jeden, der 0heute benutzt ... ähm ... hoffentlich haben sie gute Kenntnisse über reguläre Ausdrücke ...


1
Das sind einige ziemlich gute Punkte, muss ich zugeben. Ich bin froh, dass C ++ 0x einen Null-Typ haben wird. Ich denke, das wird viele Dinge sauberer machen.
Rob

2
@ Richard, warum nicht das Gegenteil tun? Sie können Meyers nullptr_t verwenden. Wenn 0x verfügbar ist, entfernen Sie das #includeund bleiben auf der sicheren Seite.
fnieto - Fernando Nieto

15
#define NULL nullptrscheint gefährlich. Ob gut oder schlecht, viele Legacy-Codes verwenden NULL für andere Dinge als 0. Beispielsweise werden Handles häufig als integraler Typ implementiert, und das Festlegen auf NULList nicht ungewöhnlich. Ich habe sogar Missbräuche wie NULLdas Setzen von a charauf einen Nullterminator gesehen.
Adrian McCarthy

8
@AdrianMcCarthy: Ich würde nur sagen, dass es gefährlich ist, wenn die Gefahr besteht, dass der Code stillschweigend kompiliert wird und eine andere Bedeutung hat. Ich bin mir ziemlich sicher, dass dies nicht der Fall ist, sodass tatsächlich alle falschen Verwendungen von NULL erkannt werden.
Richard Corden

3
@RichardCorden: Ähm, das setzt voraus, dass diese anderen Verwendungen NULLtatsächlich falsch sind. Viele APIs werden seit langem NULLmit Handles verwendet, und das ist in der Tat die dokumentierte Verwendung mit vielen von ihnen. Es ist nicht pragmatisch, diese plötzlich zu brechen und zu erklären, dass sie es falsch machen.
Adrian McCarthy

45

Verwenden Sie NULL. NULL zeigt Ihre Absicht. Dass es 0 ist, ist ein Implementierungsdetail, das keine Rolle spielen sollte.


28
0 ist kein Implementierungsdetail. Der Standard definiert 0 als das Bitmuster, das einen Nullzeiger darstellt.
Ferruccio

5
Als ob ..!! Alter, C ++ ist eine einfache Sprache! Verwenden Sie 0, es ist eine bekannte Redewendung.
Hasen

8
Ich verstehe, dass es ein Teil des Standards ist. Es ist ein Implementierungsdetail, was das Lesen des Codes betrifft. Der Leser sollte denken, dass "NULL-Zeiger" nicht "0" ist, was in diesem Fall NULL-Zeiger bedeutet, keine Zahl, mit der ich rechnen könnte. "
Andy Lester

2
+1. Einverstanden mit Andy. @Ferruccio, Implementierung Detail der Idee des Programmierers ist nicht die gleiche wie die Compiler Implementierung definiert
Benutzer

Wenn Sie NULL in einem einfachen Code ohne komplexen Header verwenden, wird der Fehler "NULL ist in diesem Bereich nicht definiert"
ArtificiallyIntelligence

37

Ich benutze immer:

  • NULL für Zeiger
  • '\0' für Zeichen
  • 0.0 für Schwimmer und Doppel

wo 0 würde gut tun. Es ist eine Frage der Signalabsicht. Das heißt, ich bin nicht anal darüber.


24
Sie sollten wahrscheinlich 0.0F für Floats verwenden, um die implizite
Typumwandlung

35

Ich habe vor langer Zeit aufgehört, NULL zugunsten von 0 zu verwenden (wie auch die meisten anderen Makros). Ich habe dies nicht nur getan, weil ich Makros so weit wie möglich vermeiden wollte, sondern auch, weil NULL in C- und C ++ - Code überstrapaziert zu sein scheint. Es scheint immer dann verwendet zu werden, wenn ein 0-Wert benötigt wird, nicht nur für Zeiger.

Bei neuen Projekten habe ich dies in einen Projektheader eingefügt:

static const int nullptr = 0;

Wenn nun C ++ 0x-kompatible Compiler eintreffen, muss ich nur noch diese Zeile entfernen. Ein netter Vorteil davon ist, dass Visual Studio nullptr bereits als Schlüsselwort erkennt und es entsprechend hervorhebt.


4
Die Verwendung von NULL ist langfristig portabler. 'nullptr' ist für einige Plattformen verfügbar und für andere nicht. Ihre Lösung hier erfordert, dass Sie den Präprozessor um Ihre Deklaration verwenden, um sicherzustellen, dass er nur bei Bedarf vorhanden ist. NULL erledigt dies automatisch.
Richard Corden

6
Ich bin nicht einverstanden. Es wird kurzfristig weniger portabel sein, bis die Compiler aufholen. Langfristig wird es genauso tragbar und vielleicht etwas lesbarer sein.
Ferruccio

4
Außerdem können Sie für Ihren Nicht-C ++ 0x-Compiler immer #define nullptr NULL definieren.
Anteru

20
    cerr << sizeof(0) << endl;
    cerr << sizeof(NULL) << endl;
    cerr << sizeof(void*) << endl;

    ============
    On a 64-bit gcc RHEL platform you get:
    4
    8
    8
    ================

Die Moral der Geschichte. Sie sollten NULL verwenden, wenn Sie mit Zeigern arbeiten.

1) Es erklärt Ihre Absicht (lassen Sie mich nicht Ihren gesamten Code durchsuchen, um herauszufinden, ob eine Variable ein Zeiger oder ein numerischer Typ ist).

2) In bestimmten API-Aufrufen, die variable Argumente erwarten, verwenden sie einen NULL-Zeiger, um das Ende der Argumentliste anzuzeigen. In diesem Fall kann die Verwendung einer '0' anstelle von NULL zu Problemen führen. Auf einer 64-Bit-Plattform möchte der Aufruf von va_arg einen 64-Bit-Zeiger, Sie übergeben jedoch nur eine 32-Bit-Ganzzahl. Scheint mir, als ob Sie sich darauf verlassen, dass die anderen 32-Bit für Sie auf Null gesetzt werden? Ich habe bestimmte Compiler gesehen (z. B. Intels ICPC), die nicht so freundlich sind - und dies hat zu Laufzeitfehlern geführt.


NULLVielleicht ist es nicht tragbar und nicht sicher. Möglicherweise gibt es noch Plattformen #define NULL 0(laut Stroustrups FAQ: Soll ich NULL oder 0 verwenden? Zitiert von der obersten Frage und es gehört zu den ersten Suchergebnissen). Zumindest in älteren C ++ 0hat eine spezielle konzeptionelle Bedeutung im Zeigerkontext. Sie sollten nicht konkret über Bits nachdenken. Beachten Sie auch , dass in verschiedenen Kontexten integer ( short, int, long long) „ sizeof(0)“ anders sein wird. Ich denke, diese Antwort ist ein bisschen falsch.
FooF

(Persönlich als C - Programmierer im täglichen Leben, kam ich auf diese Frage zu besuchen , zu verstehen , warum Menschen verwenden mögen , NULLanstatt (char *)0, (const char *)0oder (struct Boo *)0oder (void *)0oder was auch immer zum Ausdruck bringt die Absicht deutlicher -. , Ohne (meiner Meinung nach ) zu umständlich)
foof

Stimmen Sie ab. Es passiert beim msvc2013 C Compiler. In 64-Bit ist 0 beim Konvertieren in einen Zeiger keine Garantie dafür, dass es sich um einen NULL-Zeiger handelt.
PengMiao

16

Wenn ich mich richtig erinnere, wird NULL in den von mir verwendeten Headern anders definiert. Für C ist es als (void *) 0 definiert und für C ++ als nur 0. Der Code sah ungefähr so ​​aus:

#ifndef __cplusplus
#define NULL (void*)0
#else
#define NULL 0
#endif

Persönlich verwende ich immer noch den NULL-Wert, um Nullzeiger darzustellen. Es wird deutlich, dass Sie einen Zeiger anstelle eines integralen Typs verwenden. Ja, intern ist der NULL-Wert immer noch 0, aber er wird nicht als solcher dargestellt.

Außerdem verlasse ich mich nicht auf die automatische Konvertierung von Ganzzahlen in boolesche Werte, sondern vergleiche sie explizit.

Zum Beispiel bevorzugen:

if (pointer_value != NULL || integer_value == 0)

eher, als:

if (pointer_value || !integer_value)

Es genügt zu sagen, dass dies alles in C ++ 11 behoben ist, wo man es einfach nullptranstelle von verwenden kann NULL, und nullptr_tdas ist auch der Typ von a nullptr.


15

Ich würde sagen, die Geschichte hat gesprochen und diejenigen, die sich für die Verwendung von 0 (Null) aussprachen, waren falsch (einschließlich Bjarne Stroustrup). Die Argumente für 0 waren hauptsächlich Ästhetik und "persönliche Präferenz".

Nach der Erstellung von C ++ 11 mit seinem neuen Typ nullptr haben einige Compiler (mit Standardparametern) angefangen, sich über die Übergabe von 0 an Funktionen mit Zeigerargumenten zu beschweren, da 0 kein Zeiger ist.

Wenn der Code mit NULL geschrieben worden wäre, hätte eine einfache Suche und Ersetzung über die Codebasis durchgeführt werden können, um ihn stattdessen auf nullptr zu setzen. Wenn Sie mit Code stecken bleiben, der mit der Auswahl von 0 als Zeiger geschrieben wurde, ist es weitaus mühsamer, ihn zu aktualisieren.

Und wenn Sie jetzt neuen Code in den C ++ 03-Standard schreiben müssen (und nullptr nicht verwenden können), sollten Sie wirklich nur NULL verwenden. Dies erleichtert Ihnen die Aktualisierung in Zukunft erheblich.


11

Normalerweise verwende ich 0. Ich mag keine Makros und es gibt keine Garantie dafür, dass ein von Ihnen verwendeter Header eines Drittanbieters NULL nicht neu definiert, um etwas Seltsames zu sein.

Sie können ein nullptr-Objekt verwenden, wie von Scott Meyers und anderen vorgeschlagen, bis C ++ ein nullptr-Schlüsselwort erhält:

const // It is a const object...
class nullptr_t 
{
public:
    template<class T>
    operator T*() const // convertible to any type of null non-member pointer...
    { return 0; }

    template<class C, class T>
    operator T C::*() const   // or any type of null member pointer...
    { return 0; }

private:
    void operator&() const;  // Can't take address of nullptr

} nullptr = {};

Google "nullptr" für weitere Informationen.


9
Jede Drittanbieter-Bibliothek, die NULL für etwas anderes als 0 definiert (oder (void*)0wenn sie als C-Code kompiliert wird), fragt nur nach Problemen und sollte nicht verwendet werden.
Adam Rosenfield

2
Haben Sie jemals eine Bibliothek gesehen, die NULL neu definiert? Je? Wenn eine solche Bibliothek jemals existieren würde, hätten Sie größere Probleme als die neu definierte NULL, z. B. dass Sie eine Bibliothek verwenden, die dumm genug ist, NULL neu zu definieren.
Andy Lester

1
Vor weit über einem Jahrzehnt erinnere ich mich vage daran, dass ich mich mit einigen Headern von Drittanbietern befassen musste, möglicherweise entweder Orbix oder ObjectStore, die NULL definiert haben. Ich glaube, ich habe einen pathologischen Hass auf Makros, nachdem ich mehrere Tage und Nächte damit verbracht habe, verschiedene Header von Drittanbietern dazu zu bringen, mit windows.h zu arbeiten.
Jon-Hanson

2
"Mag Makros nicht mögen" ist eine seltsame Kritik an einem objektähnlichen #define. Vielleicht wollen Sie damit sagen, dass Sie den C-Präprozessor nicht mögen?
Andrew Prock

@ Andrew - Der einzige Vorteil von NULLOver (type *)0ist die Suchbarkeit, scheint mir. Ansonsten scheint es unnötig zu verschleiern, wenn es kein C-Idiom wäre. Ich persönlich denke, die Redewendung NULL, sich überall zu verbreiten , verdient es zu sterben. NULList meiner Meinung nach nutzloses Makro. Occams Rasiermesser hat hier etwas zu tun ...
FooF

11

Ich habe einmal an einer Maschine gearbeitet, auf der 0 eine gültige Adresse war und NULL als spezieller Oktalwert definiert wurde. Auf diesem Computer (0! = NULL), also Code wie

char *p;

...

if (p) { ... }

würde nicht so funktionieren, wie Sie es erwarten. Du musstest schreiben

if (p != NULL) { ... }

Obwohl ich glaube, dass die meisten Compiler NULL heutzutage als 0 definieren, erinnere ich mich noch an die Lektion aus jenen Jahren: NULL ist nicht unbedingt 0.


26
Sie haben keinen kompatiblen Compiler verwendet. Der Standard sagt NULL ist 0 und dass der Compiler 0 in einem Zeiger Kontext in einen richtigen echten Nullwert für den Bogen umwandeln sollte.
Evan Teran

17
Ja, du hast recht. Dies war Mitte der 80er Jahre, bevor ANSI einen C-Standard produzierte. Damals gab es keine Compliance, und Compiler-Autoren konnten die Sprache nach eigenem Ermessen interpretieren. Deshalb war ein Standard notwendig.
mxg

9

Ich denke, der Standard garantiert, dass NULL == 0 ist, also können Sie beides tun. Ich bevorzuge NULL, weil es Ihre Absicht dokumentiert.


Wenn Sie verschachtelte Strukturen haben, foo.bar_ptr = (Bar *) 0drückt das Sprichwort die Absicht viel klarer aus als foo.bar_ptr = NULL. Diese Angewohnheit ermöglicht es dem Compiler auch, Missverständnisfehler für Sie zu erkennen. Für mich foo.bar_ptr = 0drückt die Absicht aus und verwendet, NULLwenn ich weiß, dass foo.bar_ptrdas ein Zeiger ist.
FooF

9

Die Verwendung von 0 oder NULL hat den gleichen Effekt.

Dies bedeutet jedoch nicht, dass beide gute Programmierpraktiken sind. Angesichts der Tatsache, dass es keinen Unterschied in der Leistung gibt, ist die Wahl einer Option mit niedrigem Bewusstsein anstelle einer agnostischen / abstrakten Alternative eine schlechte Programmierpraxis. Helfen Sie den Lesern Ihres Codes, Ihren Denkprozess zu verstehen .

NULL, 0, 0.0, '\ 0', 0x00 und was auch immer übersetzen sich in dasselbe, sind jedoch unterschiedliche logische Einheiten in Ihrem Programm. Sie sollten als solche verwendet werden. NULL ist ein Zeiger, 0 ist eine Menge, 0x0 ist ein Wert, dessen Bits interessant sind usw. Sie würden einem Zeiger nicht '\ 0' zuweisen, unabhängig davon, ob er kompiliert wird oder nicht.

Ich weiß, dass einige Gemeinden dazu ermutigen, fundiertes Wissen über eine Umwelt zu demonstrieren, indem sie die Verträge der Umwelt brechen. Verantwortliche Programmierer erstellen jedoch wartbaren Code und halten solche Praktiken aus ihrem Code heraus.


5

Seltsam, niemand, einschließlich Stroustroup, erwähnte das. Während viel über Standards und Ästhetik gesprochen wurde, bemerkte niemand, dass dies der Fall ist gefährlich zu verwenden , 0in NULL‚s statt, zum Beispiel in variable Argumentliste auf der Architektur , wo sizeof(int) != sizeof(void*). Wie Stroustroup bevorzuge ich 0aus ästhetischen Gründen, aber man muss darauf achten, es nicht dort zu verwenden, wo sein Typ mehrdeutig sein könnte.


Und in diesen gefährlichen Orten können Sie immer noch verwenden , 0sofern Sie angeben , welche 0Sie bedeuten - zum Beispiel (int *)0, (char *)0, (const char *)0oder (void *)0oder (unsigned long long) 0oder was auch immer. Dies drückt meiner Meinung nach die Absicht viel klarer aus als NULL.
FooF

1
Sicher, wenn Sie nicht wissen, wofür es NULLsteht.
Michael Krelin - Hacker

Ich persönlich finde es etwas unangenehm, etwas unnötig zu besetzen , (void *)wenn ich den genauen Typ verwenden könnte. Ich habe absichtlich ein Beispiel für eine (normalerweise) 64-Bit-Ganzzahl in der Liste angegeben, da diese dem Zeiger des Zeigers entspricht. Wenn ich mich daran erinnere, dass älteres C ++ NULLals 0genau definiert wurde (es ist Jahre her, seit ich in C ++ programmiert habe), dann sehen wir keine Verbesserung der Programmkorrektheit. Der neuere C ++ - Standard bietet glücklicherweise ein nullptrSchlüsselwort, sodass wir diese NULLHässlichkeit und die ganze Kontroverse beim Schreiben von neuerem C ++ loswerden können .
FooF

Nun, deshalb wurde das Casting zu (void*)abstrahiert NULL. Und NULLdrückt die Absicht die meiste Zeit ganz klar aus. Und ich denke, deine Erinnerung ist falsch. Ich bin mir nicht sicher über Standards, aber in der Praxis glaube ich, dass es so war (void*)0. Und ja, es nullptrist ein netter Prettifier, obwohl es sich um dasselbe handelt NULL- das Angeben eines Nullzeigers ohne Angabe des Typs.
Michael Krelin - Hacker

1
@FooF, auf einigen Plattformen - vielleicht. In meiner Realität hat es funktioniert und daher vermute ich, dass es als Zeiger definiert wurde. Was die Robustheit betrifft, ja, was ich damit sagen wollte, dass die Verwendung nullptrdieselbe Botschaft trägt wie NULL, dass es nur darum ging, die Absicht auszudrücken, die Sie am Anfang erwähnt haben. (Vorverarbeitung NULLauf modernen gccErträgen __null, was auch immer es ist).
Michael Krelin - Hacker

4

Ich versuche, die ganze Frage zu vermeiden, indem ich nach Möglichkeit C ++ - Referenzen verwende. Eher, als

void foo(const Bar* pBar) { ... }

Sie können oft schreiben

void foo(const Bar& bar) { ... }

Das funktioniert natürlich nicht immer. Nullzeiger können jedoch überbeansprucht werden.


3

Ich bin mit Stroustrup in diesem Fall :-) Da NULL nicht Teil der Sprache ist, bevorzuge ich die Verwendung von 0.


3

Meistens persönliche Präferenz, obwohl man argumentieren könnte, dass NULL es ziemlich offensichtlich macht, dass das Objekt ein Zeiger ist, der derzeit auf nichts zeigt, z

void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used

IIRC, der Standard verlangt nicht, dass NULL 0 ist, daher ist es wahrscheinlich am besten für Ihren Compiler, die in <stddef.h> definierten Elemente zu verwenden.

Eine weitere Facette des Arguments ist, ob Sie logische Vergleiche (implizite Umwandlung in Bool) oder Explizitätsprüfung gegen NULL verwenden sollten, aber das hängt auch von der Lesbarkeit ab.


3

Ich bevorzuge die Verwendung von NULL, da klar ist, dass Ihre Absicht darin besteht, dass der Wert einen Zeiger und keinen arithmetischen Wert darstellt. Die Tatsache, dass es sich um ein Makro handelt, ist bedauerlich, aber da es so tief verwurzelt ist, besteht nur eine geringe Gefahr (es sei denn, jemand tut etwas wirklich ohne Kopf). Ich wünschte, es wäre von Anfang an ein Schlüsselwort, aber was können Sie tun?

Trotzdem habe ich kein Problem damit, Zeiger als Wahrheitswerte an sich zu verwenden. Genau wie bei NULL ist es eine tief verwurzelte Redewendung.

C ++ 09 wird das nullptr-Konstrukt hinzufügen, das meiner Meinung nach längst überfällig ist.


1

Ich benutze immer 0. Nicht aus irgendeinem Grund, nur weil ich beim ersten Lernen von C ++ etwas gelesen habe, das die Verwendung von 0 empfohlen hat, und ich habe es einfach immer so gemacht. Theoretisch könnte es ein Verwirrungsproblem bei der Lesbarkeit geben, aber in der Praxis bin ich in Tausenden von Arbeitsstunden und Millionen von Codezeilen noch nie auf ein solches Problem gestoßen. Wie Stroustrup sagt, ist es wirklich nur ein persönliches ästhetisches Problem, bis der Standard nullptr wird.


1

Jemand hat es mir einmal gesagt ... Ich werde NULL auf 69 neu definieren. Seitdem benutze ich es nicht mehr: P.

Es macht Ihren Code ziemlich anfällig.

Bearbeiten:

Nicht alles im Standard ist perfekt. Das Makro NULL ist eine implementierungsdefinierte C ++ - Nullzeigerkonstante, die nicht vollständig mit dem C NULL-Makro kompatibel ist. Neben dem impliziten Ausblenden des Typs wird es in ein nutzloses und fehleranfälliges Tool konvertiert.

NULL verhält sich nicht als Nullzeiger, sondern als O / OL-Literal.

Sagen Sie mir, das nächste Beispiel ist nicht verwirrend:

void foo(char *); 
void foo(int); 
foo(NULL); // calls int version instead of pointer version! 

Aus diesem Grund erscheint im neuen Standard std :: nullptr_t

Wenn Sie nicht auf den neuen Standard warten und einen Nullptr verwenden möchten, verwenden Sie mindestens einen anständigen wie den von Meyers vorgeschlagenen (siehe jon.h-Kommentar).


5
NULList ein genau definierter Teil des C ++ - Standards. Wenn Sie Personen, die Standardmakros neu definieren möchten, Code in Ihrem Projekt bearbeiten lassen, wird Ihr Code "anfällig". mit NULLtut nicht.
CB Bailey

1

Nun, ich argumentiere dafür, dass ich, wann immer möglich, überhaupt keine 0- oder NULL-Zeiger verwende.

Ihre Verwendung führt früher oder später zu Segmentierungsfehlern in Ihrem Code. Nach meiner Erfahrung ist dies und Zeiger in gereral eine der größten Fehlerquellen in C ++

Außerdem führt dies zu "if-not-null" -Anweisungen im gesamten Code. Viel schöner, wenn Sie sich immer auf einen gültigen Zustand verlassen können.

Es gibt fast immer eine bessere Alternative.


2
Ein garantierter Segmentierungsfehler (und er wird auf modernen Systemen garantiert, wenn Sie dereferenzieren 0) ist nützlich für das Debuggen. Viel besser, als zufälligen Müll zu dereferenzieren und herauszufinden, wer welches Ergebnis hat.
Leichtigkeitsrennen im Orbit

-4

Das Setzen eines Zeigers auf 0 ist einfach nicht so klar. Vor allem, wenn Sie eine andere Sprache als C ++ verwenden. Dies beinhaltet sowohl C als auch Javascript.

Ich habe mich kürzlich mit einem Code wie diesem beschäftigt:

virtual void DrawTo(BITMAP *buffer) =0;

für die reine virtuelle Funktion zum ersten Mal. Ich dachte, es wäre eine Woche lang ein magischer Jiberjash. Als mir klar wurde, dass der Funktionszeiger nur auf a gesetzt wurde null(da virtuelle Funktionen in den meisten Fällen nur Funktionszeiger für C ++ sind), habe ich mich selbst getreten.

virtual void DrawTo(BITMAP *buffer) =null;

wäre weniger verwirrend gewesen als diese Basterdation ohne den richtigen Abstand zu meinen neuen Augen. Eigentlich frage ich mich, warum C ++ keine Kleinbuchstaben verwendet, nullso wie es jetzt Kleinbuchstaben falsch und wahr verwendet.


Im Allgemeinen bevorzuge ich NULl gegenüber 0 für Zeiger. Jedoch '= 0;' ist die idiomatische Methode, um eine reine virtuelle Funktion in C ++ zu deklarieren. Ich würde Ihnen dringend raten, nicht '= NULL;' für diesen speziellen Fall.
Danio

Dies ist der lustigste Kommentar zu StackOverflow. Sie wissen wahrscheinlich bereits jetzt, dass das von Ihnen angegebene Beispiel eine Syntax für eine reine virtuelle Funktion und kein Zeiger ist. Und ja, @danio ist richtig, Sie sollten NULL nicht für reine virtuelle Funktionen verwenden.
Sgowd
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.