NULL gleich dem boolschen Wert false bzw. 0?
-
ich behaupte jetzt einfach mal wer in seinem Code so etwas produziert:
if(ptr) { free(ptr); }
hält sich einfach nicht an C99
man muss
if(ptr!=NULL) { free(ptr); }
schreiben - hab nichts finden können was mir sagt das in einem if ein NULL Zeiger als false interpretiert wird (auch wenn das zufällig meist so ist)
-
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ücklichfind 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 beiif (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!