Sollte man in C++ 'NULL' oder '0' für Pointer-initialisierungen nehmen?



  • Hi Leute,

    Hier noch mal die Frage:

    "Sollte man in C++ 'NULL' oder '0' für Pointer-initialisierungen nehmen?"

    Wer kann das beantworten?



  • keine ahnung ich benutze immer 0



  • mir wurde NULL beigebracht 🙂



  • Man muss das natürlich abstrahieren, um flexibel zu bleiben:

    #define NULL 0
    #define NIX NULL



  • Definitiv NULL

    1. NULL ist sofort als Pointer zu erkennen - speziell bei Vergleichen.
    2. Ist NULL afaik nicht als 0, sondern (void*)0 definiert.

    Grüße... Heiko


  • Administrator

    Ich benutze:

    #define NULL 0
    

    Aus dem einfachen Grund, dass ich bei der Umstellung von C++03 auf C++0x Suchen & Ersetzen anwenden kann, um NULL durch nullptr zu ersetzen 😉

    bwbg schrieb:

    2. Ist NULL afaik nicht als 0, sondern (void*)0 definiert.

    AFAIK nur in C, in C++ ist es eine ganz normale 0.

    Grüssli



  • Naja, eigentlich nehme ich auch NULL wenn ein Pointer mit gemeind ist, aber mein Onkel - der schon viele Jahre in C++ prgorammiert (Zeitweise auch für IBM) - meint das macht man nur in C. In C++ sollte man nur '0' verwenden. Sagt er zu mindest.
    Mhh, ich denke ich mach das auch erst mal mit NULL weiter weil man - wie bwbg bereits schrieb - das sofort als Pointer erkennt

    Gruß



  • also in c++ gibt es das NULL makro eigentlich nicht, es befindet sich nur noch in <cstddef> um kompatibilität zu gewährleisten.
    in bjarne stroustrup buch "die c++ programmiersprache" wird so freundlich erwähnte, dass wenn dieses relikt aus c-zeite umbedingt nachbilden will, sollte man es so machen:

    const int NULL=0;
    

    ansonsten nullptr ist wohl das mittel der zukunft.



  • Ganz klar:

    template <Type>
    Type* null_ptr(Type*)
    {
        return 0;
    }
    

    🤡
    Nein, üblicherweise komme ich selten mit rohen Zeigern in Berührung und wenn doch, benutze ich eigentlich immer 0. Wobei mir Draveres Argumentationsgang eigentlich schon vom Gegenteil überzeugt hat.

    Gruß
    Don06



  • Dravere schrieb:

    Ich benutze:

    #define NULL 0
    

    Aus dem einfachen Grund, dass ich bei der Umstellung von C++03 auf C++0x Suchen & Ersetzen anwenden kann, um NULL durch nullptr zu ersetzen 😉

    und warum dann nicht gleich

    #define nullptr 0
    

    ?


  • Administrator

    erklärbär schrieb:

    und warum dann nicht gleich

    #define nullptr 0
    

    ?

    Ich habe früher WinAPI und die MFC verwendet und irgendwie hab ich mich momentan daran gewöhnt. Bisher war ich noch zu faul auf das andere umzusteigen.

    Wenn schon würde ich aber das folgende empfehlen:

    int const nullptr = 0;
    

    Mit VS dann noch ein usertype.dat und dort das nullptr aufnehmen 😉

    Grüssli



  • hehe, ihr könnt probleme haben 🙄 😃



  • Ich benutze meist NULL, einfach weil ichs gewohnt bin von C und mir einbilde, dass es ersichtlicher ist was jetzt einen Zeiger initialisiert und was einen Integer.

    Allerdings kann man das NULL-Makro/WasAuchImmer auch einem Integer zuweisen, was natürlich die Kehrseite der Medaille ist.

    Ich glaub in einem von Scott Meyers Büchern gibt es einen Vorschlag wie man sich einen sicheren NULL-Zeiger basteln kann.



  • Nullzeiger schrieb:

    Ich glaub in einem von Scott Meyers Büchern gibt es einen Vorschlag wie man sich einen sicheren NULL-Zeiger basteln kann.

    was ist denn ein sicherer null-zeiger? 😕



  • sicher heißt, dass man möglichst viele der nullpointer-schweinerein nicht machen kann. bspw ihn nicht dereferenzieren kann, die zuweisung int = nullptr illegal ist, usw.
    erklärungen findet man hier, da ist auch die variante von meyers mit drin:
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf


  • Administrator

    ghorst schrieb:

    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf

    Die Lösung ist vielleicht ein geiler Workaround. Vor allem löst man damit ja auch das folgende Problem:

    void foo(int i);
    void foo(int* p); // kann man mit 0 nicht aufrufen. Mit dem Workaround aber schon.
    

    Da überlege ich es mir schwer, ob ich das nicht ab sofort so verwende.

    Grüssli



  • ghorst schrieb:

    sicher heißt, dass man möglichst viele der nullpointer-schweinerein nicht machen kann. bspw ihn nicht dereferenzieren kann, die zuweisung int = nullptr illegal ist, usw.
    erklärungen findet man hier, da ist auch die variante von meyers mit drin:
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf

    yupp, schränkt euch mal schön immer mehr und mehr ein mit eurem c++ 👍 😃



  • Dravere schrieb:

    void foo(int* p); // kann man mit 0 nicht aufrufen. Mit dem Workaround aber schon.
    

    natürlich kann man das mit 0 aufrufen...


  • Administrator

    ghorst schrieb:

    Dravere schrieb:

    void foo(int* p); // kann man mit 0 nicht aufrufen. Mit dem Workaround aber schon.
    

    natürlich kann man das mit 0 aufrufen...

    Nein kannst du nicht:

    #include <iostream>
    
    #define NULL 0
    int const null = 0;
    int const my_nullptr = 0;
    
    const    // this is a const object... 
    class { 
    public: 
    	template<class T>    // convertible to any type 
    	operator T*() const    // of null non-member 
    	{ return 0; }    // pointer... 
    
    	template<class C, class T>  // or any type of null 
    	operator T C::*() const    // member pointer... 
    	{ return 0; } 
    
    private: 
    	void operator&() const;    // whose address can't be taken 
    } nullptr = {};    // and whose name is nullptr 
    
    void foo(int i) { std::cout << "Integer" << std::endl; };
    void foo(int* p) { std::cout << "Pointer" << std::endl; };
    
    int main()
    {
        foo(0); // Gibt garantiert "Integer" aus.
        foo(NULL); // ebenso
        foo(null); // ebenso
        foo(my_nullptr); // ebenso
    
        // klar könnte man:
        foo((int*)0); // Aber das sieht hässlich aus!
        // Zudem muss man sich immer überlegen, welcher pointer jetzt benötigt wird.
    
        // Das dagegen finde ich richtig schön und sofort klar:
        foo(nullptr); // Gibt auch Pointer aus, wie es gewollt ist.
    
        return 0;
    }
    

    Grüssli



  • jetzt raffe ich, was du meinst. mein fehler. ich ging jetzt von der freistehenden foo(int*) aus und habe mich daher gewundert. klar in dem kontext wird mit der 0 immer foo(int) aufgerufen, da keine konvertierung notwendig ist.


Anmelden zum Antworten