Sind "(char *)0" und "NULL" gleich?



  • gibt doch execv*
    PS/ED: nich soooooo ganz ernst gemeint
    PSS/ED2/OT: MrMrMrMrMrMrMrN hat gesprochen, hugh @ MrBashar

    [ Dieser Beitrag wurde am 03.07.2003 um 15:47 Uhr von Mr. N editiert. ]



  • HI

    @bashar unixoides OS.. gefällt mir der Ausdruck...*aufschreib* 😉

    afaik is NULL == (void*)0

    Jedenfalls bei mir.



  • Was aber auch nicht sehr sinnvoll ist. 🙂

    class A
    {
    public:
        void foo() {};
    };
    
    void bar()
    {
        void (A:: * p)() = (void*)0; // NULL
    }
    

    Ist ungültig.

    Ich hab mal so ein schönes NULL gesehen, das mit Hilfe von templates definiert wurde. Ich glaub es war in dem Buch "How not to program C++".

    Ich kriegs leider nicht mehr ganz zusammen. Von der Idee her war es etwas mit template member functions, sowas in der Art (läuft so nicht):

    class
    {
    public:
        template <class T> operator T*() { return (T*)(0); }
        template <class T, class C> operator C::T*() { return (C::T*)(0); }
    } NULL;
    

    Das läuft so nicht, aber irgendwas in der Art war das. Kennt jemand die richtige Definition?

    Wahrscheinlich hat der Microsoft-Compiler damit aber eh Probleme.



  • weshalb nicht einfach nur 0 schreiben? (bei den arg.listen mit variabler länge von bashar musst du den typ sowieso[siehe bashar] mit angeben)
    dann auch einfach template <class T> operator T () { return (T)0; }
    *lol*
    ich glaub, irgendwas entgeht mir.



  • Nein, das wäre noch sinnloser.

    void Foo(int);
    void Foo(char*);
    
    int main()
    {
      // NULL sollte klar als Zeiger definiert sein, daher muss das hier gehen
      // und Foo(char*) muss aufgerufen werden.
      Foo(NULL);
      return 0;
    }
    

    Einfach nur 0 würde mehrdeutig sein. NULL dagegen ist ein Zeiger, und damit ist der Aufruf Foo(NULL) eindeutig definiert.



  • @cd9000
    Von welcher Sprache redest du hier?

    Einfach nur 0 würde mehrdeutig sein

    Nö. 0 hat den Typ int -> perfect match. Nix mehrdeutig.

    NULL dagegen ist ein Zeiger

    Nö.

    und damit ist der Aufruf Foo(NULL) eindeutig definiert.

    Richtig. Eindeutig ist er. Er ruft aber Foo(int) auf nicht Foo(char*).

    NULL ist in C++ eine Nullpointer-Konstante. Es kann z.B. 0 oder 0L sein. Nicht aber (void*)0 oder (char*)0.



  • NULL kann nicht als void-Pointer definiert sein, weil es in C++ im Unterschied zu C keine implizite void* -> foo* Umwandlung gibt.



  • @Hume:
    ok, 0 ist ein int. 🙂

    Aber sollte NULL nicht nur im Zusammenhang mit Zeigern auftauchen? Ich meine, NULL ist vielleicht als int definiert, aber es wird doch nur im Kontext von Zeigern benutzt, oder?

    Um auf den Code zurückzukommen:

    void Foo(int);
    void Foo(char*);
    int main()
    {
      Foo(NULL);
      return 0;
    }
    

    Hier würde ich erwarten, dass Foo(char*) aufgerufen wird. Logisch, da NULL doch ein 0-Zeiger ist. Wird es aber in C++ nicht, wie du sagst.
    Ist NULL also einfach nur ein int, der bei Bedarf (und nur bei Bedarf) in den richtigen Zeigertyp konvertiert wird?
    Warum taucht dann sowas nicht auf?

    int main()
    {
      return NULL;
    }
    


  • p.s.:
    Wie ist denn NULL im C++ Standard definiert?



  • weil es dafür EXIT_SUCCESS gibt 😃
    außerdem ist 0 kürzer zu schreiben. NULL ist doch nur wieder ein Textersetzungsgelegenheitsbenutzungsding. geht doch auch (char*)NULL wenn du explizit nen char* brauchst. nur: (char*)0 geht auch; ist kürzer. ich mag NULL nicht. und wir leben nicht in C



  • Ich habe nie gesagt, dass ich NULL mag.

    @HumeSikkins:

    NULL ist in C++ eine Nullpointer-Konstante.

    Ist das im Standard so definiert?
    Wenn ja, dann erscheint mir die template-Definition am sinnvollsten. Weil man es dann nicht fälschlicherweise als int einsetzen kann.



  • Das sinnvollste wär vielleicht, wenn es ein null Keyword wie in Ada, Java oder Eiffel (dort Void) gäbe. gcc hat das sogar IIRC, wenn man will, in Form des Schlüsselwortes __null, plus ein #define NULL __null.



  • Ist das im Standard so definiert?

    Yep. Die genaue Repräsentation von NULL ist laut Standard "implementation defined". Wichtig ist nur, dass es sich um eine Nullzeiger-Konstante handelt. Also ein Wert der im Zeigerkontext zum Nullzeiger wird. Und zwar zu einem passenden Nullzeiger.

    Wenn ja, dann erscheint mir die template-Definition am sinnvollsten

    Nein die ist totaler Käse, da sie eben *nicht* Standardkonform ist.

    Ein Standard-C++ Programm ruft in deinem Beispiel Foo(int) auf. Die Template-Null-Variante würde aber Foo(char*) aufrufen. Das ist zwar eine schöne Variante um maximale Verwirrung zu stiften, aber darum geht es beim Programmieren in der Regel nicht primär.



  • @Bashar:
    Das fände ich auch sinnvoll.

    Wobei man diese Funktionalität auch mit template-member-functions erreichen kann. Nur der VC++ mag die wohl nicht.
    Mein Code war aber wahrscheinlich auch nicht ganz korrekt, ich erinner mich nur noch dunkel daran.

    @HumeSikkins:

    Wichtig ist nur, dass es sich um eine Nullzeiger-Konstante handelt.

    Warum ist eine Nullzeiger-Konstante kein perfect match zu char*, sondern zu int?

    Zur template-Definition:

    Nein die ist totaler Käse, da sie eben *nicht* Standardkonform ist.

    Im Standard steht doch "implementation defined".
    Reicht es da nicht, dass NULL sich wie eine Nullzeigerkonstante verhält, muss es wirklich eine sein?

    [ Dieser Beitrag wurde am 03.07.2003 um 21:14 Uhr von cd9000 editiert. ]



  • Original erstellt von davie:
    ich mag NULL nicht. und wir leben nicht in C

    Für diese beiden Sätze gilt übrigens: Zusammenhang == NULL.
    In C besteht ebenfalls kein Bedarf für NULL und es kann überall durch 0 (oder '\0' oder 0ull oder 0x00 oder so) ersetzt werden. Es gilt nur, dass NULL in C als Zeiger vereinbart sein darf, aber nicht muss.



  • ok, dann hab ich falsch gedacht.



  • Warum ist eine Nullzeiger-Konstante kein perfect match zu char*, sondern zu int?

    Sorry, aber durch das Fettmachen von Zeiger wird eine Nullzeiger-Konstante nicht automatisch mehr zum Zeiger. Eine Nullzeiger-Konstante ist nun mal *kein* Zeiger und deshalb kann char* kein perfect match sein. Eine Nullzeiger-Konstant ist laut Standard: "an integral constnat expression rvalue of integer type that evaluates to zero".

    Im Standard steht doch "implementation defined".

    Es ist "implementation defined" wie NULL repräsentiert wird. Es ist aber *garantiert*, dass NULL eine Nullzeiger-Konstante (und damit *kein* Zeiger), also ein integraler Typ der zu 0 ausgewertet wird, ist. Es kann also z.B. 0 sein (int) oder 0L (long) oder was auch immer. Solange die oben zitierte Bedingung erfüllt ist.

    Reicht es da nicht, dass NULL sich wie eine Nullzeigerkonstante verhält, muss es wirklich eine sein?

    a) Deine Template-Version verhält sich nicht wie eine Nullzeiger-Konstante sondern wie die der Nullzeiger-Wert (aka Nullzeiger).

    b) Ja es muss wirklich eine Nullzeiger-Konstante sein.

    [ Dieser Beitrag wurde am 03.07.2003 um 23:30 Uhr von HumeSikkins editiert. ]



  • Wer sagt, dass das gut ist, was der Standard da definiert?



  • Ich seh's ja ein. 🙂

    @Bashar:
    Stimmt, der Standard ist zwar gut, aber nicht immer optimal.



  • Der Standard ist nun mal das auf was man sich verlässt wenn man fremden Source bearbeitet....

    [ Dieser Beitrag wurde am 04.07.2003 um 00:22 Uhr von Knuddlbaer editiert. ]


Anmelden zum Antworten