NULL gleich dem boolschen Wert false bzw. 0?



  • Vertexwahn schrieb:

    ich behaupte jetzt einfach mal wer in seinem Code so etwas produziert:

    if(ptr)
    {
        free(ptr);
    }
    

    hält sich einfach nicht an C99

    doch, wenn ptr != NULL, dann ist ptr irgendetwas ungleich 0 und das ist "wahr", was if benutzt, um den Inhalt (free(ptr)) auszuführen.



  • supertux schrieb:

    doch, wenn ptr != NULL, dann ist ptr irgendetwas ungleich 0

    FALSCH! nicht nach C99

    borg schrieb:

    NULL == 0 == false

    FALSCH - ich will wissen wie es in C99 definiert ist

    supertux schrieb:

    In Wirklichkeit kennt ANSI C weder true noch false

    wieder FALSCH



  • Oft stößt man in C Programmen auf folgende Konstrukte:

    if(ptr) 
    { 
        free(ptr); 
    }
    

    Hier wollte der Programmierer überprüfen ob ptr != NULL. Falls ja, dann soll der Speicherbereich der mit ptr verknüpft ist freigegeben werden.

    Dieser Code funktioniert auf den meisten Compilern, da NULL meistens in folgender Form definiert ist:
    NULL==(void*) 0;

    Jedoch ist es dem Compilerhersteller überlassen wie er NULL definiert. Falls NULL einmal nicht dem Wert 0 entsprechen sollte, sondern beispielsweise dem Wert 1, dann ist obiger Code nicht Funktionsfähig.

    Nach C99 müsste obiger Code korrekt wie folgt aussehen:

    if(ptr==NULL) 
    { 
        free(ptr); 
    }
    


  • Vertexwahn schrieb:

    ist nach C99 NULL mit false bzw. 0 gleichzusetzen?

    Davon ist eher nicht auszugehen. Der Standard sagt zwar nicht genau, wie NULL aussieht, er sagt aber

    C Standard schrieb:

    The macros are
    NULL
    which expands to an implementation-defined null pointer constant;

    und

    C Standard schrieb:

    An integer constant expression with the value 0, or such an expression cast to type void
    *, is called a null pointer constant.

    Dh, NULL ist eine Zeiger Konstante, die entweder ein Integral oder (void*) blabla darstellt. false ist jedoch ein rein integraler Wert. Häufig sieht man NULL wie folgt implementiert

    ((void*) 0)
    

    Folgendes wird also mit false als Parameter funktionieren, mit NULL aber nicht zwangsläufig

    void foo(int bar)
    {
        //...
    }
    

    Vertexwahn schrieb:

    Jedoch habe ich auch schon in einem C++ Buch gelsen, dass NULL nicht mit 0 gleichzusetzen ist, da es dem Compilerhersteller überlassen ist wohin NULL "zeigt"

    Dann hast du aber ein schlechtes Buch erwischt, in C++ sieht die Sache nämlich etwas anders aus. Auch hier ist NULL eine Nullzeiger Konstante. Und diese wird wie folgt definiert

    C++ Standard schrieb:

    A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.

    Üblicherweise ist NULL dabei so definiert

    #define NULL 0
    

    Vertexwahn schrieb:

    ich behaupte jetzt einfach mal wer in seinem Code so etwas produziert:

    if(ptr)
    {
        free(ptr);
    }
    

    hält sich einfach nicht an C99

    Doch, das ist absolut legaler Code. Man könnte eher sagen, dass es ungeschickt ist. Denn ein

    free(ptr);
    

    reicht vollkomen aus.



  • Vertexwahn schrieb:

    Oft stößt man in C Programmen auf folgende Konstrukte:
    [...]

    Hier wollte der Programmierer überprüfen ob ptr != NULL. Falls ja, dann soll der Speicherbereich der mit ptr verknüpft ist freigegeben werden.

    Dieser Code funktioniert auf den meisten Compilern, da NULL meistens in folgender Form definiert ist:
    NULL==(void*) 0;

    Jedoch ist es dem Compilerhersteller überlassen wie er NULL definiert. Falls NULL einmal nicht dem Wert 0 entsprechen sollte, sondern beispielsweise dem Wert 1, dann ist obiger Code nicht Funktionsfähig.

    Dann hast Du es nicht mit C zu tun, herrgottnochmal, wie oft muß man das eigentlich noch erklären? In bezug auf Nullzeiger hat sich in C99 nicht so viel geändert, Quelltext wie 'if (p)', 'if (p != 0)' oder 'if (p != NULL)' sind gleichwertig. Man kann im Zeigerkontext überall NULL durch 0 ersetzten, ohne die Bedeutung zu verändern, weil 0 dort, wie NULL, 0ul, 0x0 usw. in diesem Kontext eine Nullzeigerkonstante wird.

    http://www-info2.informatik.uni-wuerzburg.de/dclc-faq/kap1.html

    Nach C99 müsste obiger Code korrekt wie folgt aussehen:

    if(ptr==NULL) 
    { 
        free(ptr); 
    }
    

    Neinnein, besser 'if((ptr == NULL) == 1) ...'. free testet intern, ob ptr ein Nullpointer ist, was soll dieses Beispiel?



  • Außerdem besagt dein Abzug aus dem Standard, dass true 1 ist, aber als Datentyp, es wird aber nicht gesagt, dass "wahr" ebenfalls eine 1 sein soll.

    bei if(ausdruck) code; wird code ausgeführt, wenn ausdruck "wahr" ist, und "wahr" ist nicht anders als etwas, was nicht 0 ist. Und NULL ist 0 genau wie false oder '\0'. Deshalb sind if(ptr) if(ptr != NULL) if ptr(ptr != 0) gleich.

    Vertexwahn schrieb:

    supertux schrieb:

    doch, wenn ptr != NULL, dann ist ptr irgendetwas ungleich 0

    FALSCH! nicht nach C99

    doch.

    Vertexwahn schrieb:

    borg schrieb:

    NULL == 0 == false

    FALSCH - ich will wissen wie es in C99 definiert ist

    doch. NULL == (void*) 0

    Vertexwahn schrieb:

    supertux schrieb:

    In Wirklichkeit kennt ANSI C weder true noch false

    wieder FALSCH

    bis C98 gab es kein treu/false, ab C99 schon (was ich gesagt hatte)



  • Da habe ich eine schöne FAQ.



  • supertux schrieb:

    Vertexwahn schrieb:

    supertux schrieb:

    doch, wenn ptr != NULL, dann ist ptr irgendetwas ungleich 0

    FALSCH! nicht nach C99

    doch.

    Naja nicht ganz, die Nullpointerkonstante die sich hinter NULL verbirgt wird in einen Nullpointer vom Typ den ptr hat umgewandelt. Und die beiden sind jetzt ungleich wenn sie nicht denselben Wert haben, sprich nicht auf die selbe Speicherstelle zeigen1.

    1das ist nur eine von 3 Möglichkeiten, zu dem Rest am besten den Standard konsultieren, es ist etwas kompliziert zu erklären



  • mmh...

    von: http://www-info2.informatik.uni-wuerzburg.de/dclc-faq/kap1.html:
    "Antwort: Laut Sprachdefinition wird ein integraler konstanter Ausdruck mit dem Wert 0 zu einem Null-Zeiger, wenn er einem Zeiger zugewiesen oder auf Gleichheit mit einem Zeiger verglichen wird (Äquivalenzvergleich)."

    wenn, mir jetzt noch jemand sagen könnnte wo ich entsprechendes im ISO/IEC
    9899:1999 nachlesen kann, dann bin ich glücklich 😉

    find da irgendwie nichts



  • Vertexwahn schrieb:

    wenn, mir jetzt noch jemand sagen könnnte wo ich entsprechendes im ISO/IEC 9899:1999 nachlesen kann

    6.3.2.3#3



  • Damit ich es jetzt nicht falsch verstehe:

    C99 schrieb:

    An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

    sagt diese Textstelle aus das jetzt ein NULL-Pointer auch als Integer Wert 0 interpretiert werden kann - eigentlich nicht - kann ich da jetzt einfach eine Äquivalenzrelation hineininterpretieren und sagen wenn eine 0 = NULL, dann auch NULL = 0



  • Vertexwahn schrieb:

    sagt diese Textstelle aus das jetzt ein NULL-Pointer auch als Integer Wert 0 interpretiert werden kann - eigentlich nicht

    Was meinst du mit "interpretieren"? Ein Nullzeiger muss auf Bitebene nicht aus lauter Nullen bestehen, genauso kann der Wert eines Nullzeigers auch 0x12345678 oder was auch immer sein. Der Standard stellt daher sicher, dass bei

    void* a = 0;
    

    a ein Nullzeiger ist.
    Genauso wird bei

    if (a != 0)
    

    a auf einen Nullzeiger geprüft, und nicht ob jedes Bit 0 ist.



  • naja so wie ichs jetzt verstehe, ist NULL nicht unbedingt 0x0. ABER, es ist sicher gestellt das trotzdem (0==NULL) true ist.
    also: NULL==0==false 🤡



  • falls ich jetzt folgende Code hab:

    if (a)
    

    wie wertet das der Compiler aus? a ist doch ein Zeiger - ich nehm mal an das der Zeiger in einen boolschen Wert konvertiert werden muss wie geht das?



  • Vertexwahn schrieb:

    falls ich jetzt folgende Code hab:

    if (a)
    

    wie wertet das der Compiler aus? a ist doch ein Zeiger - ich nehm mal an das der Zeiger in einen boolschen Wert konvertiert werden muss wie geht das?

    wenn a auf den NULLzeiger zeigt (also a==NULL), dann ist die Bedingung nicht erfüllt und der Inhalt der if Schleife wird nicht ausgeführt.

    Wenn a auf keinen NULLzeiger zeigt, dann ist die Bedingung wahr, weil a ungleich 0 ist, also wird der Inhalt der if Schleife wird ausgeführt.



  • wenn der Nullzeigers den Wert 0x12345678, dann entspricht das doch nie dem wert 0 - da muss ja impliziet irgendwie gecastet werden



  • Vertexwahn schrieb:

    wenn der Nullzeigers den Wert 0x12345678, dann entspricht das doch nie dem wert 0 - da muss ja impliziet irgendwie gecastet werden

    Du willst 'if(p)' analysiren:

    'if ('
    Okay, -> 6.8.4.1#2
    |In both forms, the first substatement is executed if the expression compares unequal to 0.
    |In the else form, the second substatement is executed if the expression compares equal
    |to 0. If the first substatement is reached via a label, the second substatement is not
    |executed.

    Aha, 'compares unequal to 0', also ist if(expr) das gleiche wie if((expr) != 0). -> 6.5.9 (Equality operators), insb. 6.5.9#5
    |Otherwise, at least one operand is a pointer. If one operand is a pointer and the other is a
    |null pointer constant, the null pointer constant is converted to the type of the pointer. If
    |one operand is a pointer to an object or incomplete type and the other is a pointer to a
    |qualified or unqualified version of void, the former is converted to the type of the latter.

    Den Rest hatten wir schon. Wieso kramst Du immer wieder die Binärdarstellung des Zeigers intern raus? Wen interessiert die?



  • Vertexwahn
    **********

    if(ptr)
    {
    free(ptr);
    }

    Was mich mal interessiern würde WO du diese Codebeispiele ausgegraben hast. Mich würde ernsthaft das gesamte Programm dazu interessieren.

    tt



  • groovemaster schrieb:

    [Doch, das ist absolut legaler Code. Man könnte eher sagen, dass es ungeschickt ist. Denn ein

    free(ptr);
    

    reicht vollkomen aus.

    Kann man auch verschärft sehen: Mit der if- Abfrage wird ja nicht sichergestellt, daß es genau der Pointer ist, den man killen mag, sondern nur sichergestellt, daß irgendwas drinsteht, was if() nicht als false (!=0) sieht. Überlegt mal, wie groß die Chance ist, daß if() wirklich false rauskriegt ... :p

    So eine Abfrage ist also nichts als schwachsinniges 🤡 Verbraten von Rechenzeit!



  • pointercrash() schrieb:

    Überlegt mal, wie groß die Chance ist, daß if() wirklich false rauskriegt ... :p

    Beim MSC als Debug Build ziemlich klein, ich sag nur 0xcccccccc. 😃


Anmelden zum Antworten