Servus
Thorsten Haude
Moin,
ich versuche gerade, etwas Code zu verschönern, dabei stellt sich mir folgende Frage: Was ist der Unterschied zwischen (einTyp*) 0
Hier hast du eine explizite Typkonvertierung (Cast) von einem Integerliteral zu einem einTyp-Zeiger.
und NULL
Hier hast du eine implizite Typkonvertierung von einem void-Zeiger (bei neuern Standard- bibliotheken) mit dem Wert 0 zu einem einTyp-Zeiger. Ich würde diese Version wählen, bei C++ ist eigentlich die blose '0' üblich. Ciao ______________________________________________________________________________ Keinen passenden Spruch fur die SMS parat? Mit WEB.DE FreeMail kein Problem mehr! http://freemail.web.de/features?mc=021149
Moin,
* Sebastian Huber
Thorsten Haude
schrieb am 09.12.02 18:55:38: Moin,
ich versuche gerade, etwas Code zu verschönern, dabei stellt sich mir folgende Frage: Was ist der Unterschied zwischen (einTyp*) 0
Hier hast du eine explizite Typkonvertierung (Cast) von einem Integerliteral zu einem einTyp-Zeiger.
Das verstehe ich.
NULL
Hier hast du eine implizite Typkonvertierung von einem void-Zeiger (bei neuern Standard- bibliotheken) mit dem Wert 0 zu einem einTyp-Zeiger. Ich würde diese Version wählen, bei C++ ist eigentlich die blose '0' üblich.
Das nicht. Wo wird hier konvertiert, außer von 0 zu (void*) 0 ? Thorsten -- They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety. - Benjamin Franklin
Hallo, <mode type="AFAIK|AFAIR"> On Mon, 09 Dec 2002, Thorsten Haude wrote:
* Sebastian Huber
[02-12-09 20:16]: Thorsten Haude
schrieb am 09.12.02 18:55:38: ich versuche gerade, etwas Code zu verschönern, dabei stellt sich mir folgende Frage: Was ist der Unterschied zwischen (einTyp*) 0
Hier hast du eine explizite Typkonvertierung (Cast) von einem Integerliteral zu einem einTyp-Zeiger.
Das verstehe ich.
Ist aber nur bedingt richtig. Wie ich neulich gelesen habe, ist NULL (auch und gerade(!) wenn es als (void*)0 definiert ist) nicht unbedingt ein Zeiger auf die Speicheradresse 0. Definiert ist nur, dass (in C(!)) ein Cast von 0 zu einem Pointer einen ("den") ungueltigen Zeiger zu ergeben hat, der je nach Architektur u.U. eben nicht "0x0" ist. Ein Vergleich von (void*)0 == (int)0 bzw. ptr == 0 muss aber (IIRC) uebrigens "Wahr" ergeben (wenn ptr == NULL bzw. wenn ptr ungueltig ist)... Dieses Verhalten muss durch die Implementation des Compilers gewaehrt werden.
NULL
Hier hast du eine implizite Typkonvertierung von einem void-Zeiger (bei neuern Standard- bibliotheken) mit dem Wert 0 zu einem einTyp-Zeiger. Ich würde diese Version wählen, bei C++ ist eigentlich die blose '0' üblich.
s.o. casts von 0 auf Zeiger bzw. Vergleiche von Zeigern mit 0 (oder indirekt ueber ein NULL, z.B. eben (void*)0) haben obiges Verhalten zu zeigen -- egal auf was nun der Zeiger zeigt / mit was verglichen wird.
Das nicht. Wo wird hier konvertiert, außer von 0 zu (void*) 0 ?
s.o. "per definitionem" muss es egal sein. Allerdings macht es einen (semantischen(?)) Unterschied, ob nun explizit zwei Pointer (ptr == (void*)0) oder mit implizitem cast (ptr == 0) verglichen (oder zugewiesen) wird. In der Praxis auf x86-Hardwaere macht es allerdings AFAIK keinen Unterschied, da der "ungueltige Zeiger" eben (AFAIK) als ein Zeiger auf die Adresse 0x0 definiert ist, d.h. auch im Maschinencode wird mit 0 verglichen/zugewiesen ;) Auf anderer Hardware kann das aber durchaus anders sein -- das Verhalten in C (und C++) muss aber das gleiche sein, der Compiler muss dort eben passenden Code erzeugen. Der Vergleich ptr == NULL ist IMO vorzuziehen, sofern die Implementation ein NULL bietet. Ansonsten sollte man wohl NULL selber zu (void*)0 definieren, um explizit Pointer mit einem Pointer zu vergleichen. </mode> -dnh -- I sense much distrust in you. Distrust leads to cynicism, cynicism leads to bitterness, bitterness leads to the Awareness Of True Reality which is referred to by those-who-lack-enlightenment as "paranoia". I approve. -- David P. Murphy in the SDM
Hi! On Monday 09 December 2002 22:42, David Haller wrote:
Hallo,
<mode type="AFAIK|AFAIR">
On Mon, 09 Dec 2002, Thorsten Haude wrote:
* Sebastian Huber
[02-12-09 20:16]: Thorsten Haude
schrieb am 09.12.02 18:55:38: ich versuche gerade, etwas Code zu verschönern, dabei stellt sich mir folgende Frage: Was ist der Unterschied zwischen (einTyp*) 0
Hier hast du eine explizite Typkonvertierung (Cast) von einem Integerliteral zu einem einTyp-Zeiger.
Das verstehe ich.
Ist aber nur bedingt richtig. Wie ich neulich gelesen habe, ist NULL (auch und gerade(!) wenn es als (void*)0 definiert ist) nicht unbedingt ein Zeiger auf die Speicheradresse 0.
Das ist schon exakt richtig. Es ist ein expliziter Cast von einem Integerliteral zu einem einTyp-Zeiger. Dass sich das Bitmuster von Integer 0 und Zeiger 0 unterscheiden kann, ist, wie du ja auch schreibst, moeglich, aber egal. So was passiert ja auch bei der Umwandlung von int nach float.
Definiert ist nur, dass (in C(!)) ein Cast von 0 zu einem Pointer einen ("den") ungueltigen Zeiger zu ergeben hat, der je nach Architektur u.U. eben nicht "0x0" ist. Ein Vergleich von (void*)0 == (int)0 bzw. ptr == 0 muss aber (IIRC) uebrigens "Wahr" ergeben (wenn ptr == NULL bzw. wenn ptr ungueltig ist)...
Dieses Verhalten muss durch die Implementation des Compilers gewaehrt werden.
NULL
Hier hast du eine implizite Typkonvertierung von einem void-Zeiger (bei neuern Standard- bibliotheken) mit dem Wert 0 zu einem einTyp-Zeiger. Ich würde diese Version wählen, bei C++ ist eigentlich die blose '0' üblich.
s.o. casts von 0 auf Zeiger bzw. Vergleiche von Zeigern mit 0 (oder indirekt ueber ein NULL, z.B. eben (void*)0) haben obiges Verhalten zu zeigen -- egal auf was nun der Zeiger zeigt / mit was verglichen wird.
Das nicht. Wo wird hier konvertiert, außer von 0 zu (void*) 0 ?
s.o. "per definitionem" muss es egal sein. Allerdings macht es einen (semantischen(?)) Unterschied, ob nun explizit zwei Pointer (ptr == (void*)0) oder mit implizitem cast (ptr == 0) verglichen (oder zugewiesen) wird.
In der Praxis auf x86-Hardwaere macht es allerdings AFAIK keinen Unterschied, da der "ungueltige Zeiger" eben (AFAIK) als ein Zeiger auf die Adresse 0x0 definiert ist, d.h. auch im Maschinencode wird mit 0 verglichen/zugewiesen ;) Auf anderer Hardware kann das aber durchaus anders sein -- das Verhalten in C (und C++) muss aber das gleiche sein, der Compiler muss dort eben passenden Code erzeugen.
Der Vergleich ptr == NULL ist IMO vorzuziehen, sofern die Implementation ein NULL bietet. Ansonsten sollte man wohl NULL selber zu (void*)0 definieren, um explizit Pointer mit einem Pointer zu vergleichen.
</mode>
-dnh
Am Mon, 2002-12-09 um 22.42 schrieb David Haller:
Hallo,
<mode type="AFAIK|AFAIR">
Der Vergleich ptr == NULL ist IMO vorzuziehen, sofern die Implementation ein NULL bietet.
Dazu zwei Dinge: * Halbwegs moderne Systeme/Implementationen bieten NULL immer an. * In der Praxis führt Verwendung von NULL in C++ zu Portabilitätsproblemen. Grund: Die Zuweisung von NULL in C++ hat eine Reihe von impliziten Typecasts zur Folge, die, abhängig von der verwendeten C++-Toolchain, unter Umständen scheitern können. Hingegen ist (type*) 0 immer eindeutig, typenstreng und vermeidet implizite Typecasts. Der Streit darüber (ob man in C++ (type*)0, NULL, oder gar 0 verwenden sollte) ist so alt wie C++ selbst. Entsprechende Diskussionen finden sich in zahlreichen C++-Diskussionsforen
Ansonsten sollte man wohl NULL selber zu (void*)0 definieren, um explizit Pointer mit einem Pointer zu vergleichen. Definitiv nein.
NULL hat vom System bereitgestellt zu werden. Seine eigene Definition von NULL zu verwenden ist ein Hack aus C-Urzeiten und spätestens seit ANSI-C (aka c89) obsolet. Ralf
Moin,
* David Haller
On Mon, 09 Dec 2002, Thorsten Haude wrote:
* Sebastian Huber
[02-12-09 20:16]: Thorsten Haude
schrieb am 09.12.02 18:55:38: ich versuche gerade, etwas Code zu verschönern, dabei stellt sich mir folgende Frage: Was ist der Unterschied zwischen (einTyp*) 0
Hier hast du eine explizite Typkonvertierung (Cast) von einem Integerliteral zu einem einTyp-Zeiger.
Das verstehe ich.
Ist aber nur bedingt richtig. Wie ich neulich gelesen habe, ist NULL (auch und gerade(!) wenn es als (void*)0 definiert ist) nicht unbedingt ein Zeiger auf die Speicheradresse 0.
Was genau ist jetzt nur bedingt richtig?
NULL
Hier hast du eine implizite Typkonvertierung von einem void-Zeiger (bei neuern Standard- bibliotheken) mit dem Wert 0 zu einem einTyp-Zeiger. Ich würde diese Version wählen, bei C++ ist eigentlich die blose '0' üblich.
s.o. casts von 0 auf Zeiger bzw. Vergleiche von Zeigern mit 0 (oder indirekt ueber ein NULL, z.B. eben (void*)0) haben obiges Verhalten zu zeigen -- egal auf was nun der Zeiger zeigt / mit was verglichen wird.
Jepp, jetzt ist es klar geworden. Ihr habt Sachen vorrausgesetzt, über die wir noch garnicht gesprochen hatten, aber inzwischen bin ich dahintergekommen.
Das nicht. Wo wird hier konvertiert, außer von 0 zu (void*) 0 ?
s.o. "per definitionem" muss es egal sein.
Hier hast Du mich wieder verloren. Du schreibst doch die ganze Zeit, daß Zeiger und Integer nicht gleich sind!?
Der Vergleich ptr == NULL ist IMO vorzuziehen, sofern die Implementation ein NULL bietet.
NULL ist ANSI-C. Thorsten -- I believe that there are more instances of the abridgment of the freedom of the people by gradual and silent encroachment than by violent and sudden usurpations. - James Madison
Hallo, On Tue, 17 Dec 2002, Thorsten Haude wrote:
* David Haller
[2002-12-09 22:42]: Das nicht. Wo wird hier konvertiert, außer von 0 zu (void*) 0 ?
s.o. "per definitionem" muss es egal sein.
Hier hast Du mich wieder verloren. Du schreibst doch die ganze Zeit, daß Zeiger und Integer nicht gleich sind!?
Sind sie ja nicht. Nur definiert der Standard (IIRC), dass bei Vergleichen etc. ein 0 / (void*)0 zu INVALID_POINTER konvertiert werden muss. D.h.: foo * bar; if( bar == 0 ) /* -> bar == INVALID_POINTER? */ if( bar == (void*)0 ) /* -> bar == INVALID_POINTER? */ Dabei "muss" INVALID_POINTER _nicht_ 0x0 sein. In der Praxis _ist_ es aber meist (immer?) 0x0. Eine Implementation koennte z.B. folgendes machen: sizeof(ptr_t) := 4 sizeof(int64_t) := 8 INVALID_POINTER := (int64_t)-1 ueber den (Un)Sinn einer solchen Konstruktion will ich nicht reden, aber es kann z.B. HW geben, die irgendein Register oder sonstwas in der Richtung zur Verfuegung stellt oder weiss der Geier.
Der Vergleich ptr == NULL ist IMO vorzuziehen, sofern die Implementation ein NULL bietet.
NULL ist ANSI-C.
[ ] alle Compiler setzen ANSI-C vollstaendig und korrekt um -dnh -- Die Tastatur finden Sie, indem Sie das Kabel verfolgen, ds mit einem 5poligen DIN-Stecker an der Rückseite Ihres Rechners angebracht ist. [CrossPoint-Hilfe]
Moin,
* David Haller
Der Vergleich ptr == NULL ist IMO vorzuziehen, sofern die Implementation ein NULL bietet.
NULL ist ANSI-C.
[ ] alle Compiler setzen ANSI-C vollstaendig und korrekt um
Ja, aber wir reden hier von NULL. Welcher Compiler kennt das nicht? Thorsten -- Who exactly was the jackass that decided emails needed to be able to execute scripts automatically? Could he meet me in the alley for five minutes? - 0xA
participants (4)
-
David Haller
-
Ralf Corsepius
-
Sebastian Huber
-
Thorsten Haude