2010-05-05 8 views
8

Das mag seltsam erscheinen, aber in C (size_t) (void *) ist 0 == 0 nicht durch die Sprachspezifikation garantiert. Compiler dürfen einen beliebigen Wert für null verwenden (obwohl sie fast immer 0 verwenden).Gibt es einen Unterschied zwischen null und 0 beim Zuweisen von Zeigern in unsicheren Code?

In C# können Sie einem Zeiger in unsicheren Code null oder (T *) 0 zuweisen.

  1. Gibt es einen Unterschied?
  2. (long) (void *) 0 == 0 (garantiert oder nicht um es anders auszudrücken: IntPtr.Zero.ToInt64() == 0)

MSDN hat dies über IntPtr zu sagen. Null:

"Der Wert dieses Feldes entspricht nicht Null." Nun, wenn Sie mit C-Code kompatibel sein wollen, macht das sehr viel Sinn - es wäre für Interop wertlos, wenn es nicht in einen C-Null-Zeiger umgewandelt würde. Aber ich möchte wissen, ob IntPtr.Zero.ToInt64() == 0 die möglicherweise möglich ist, auch wenn intern IntPtr.Zero ist ein anderer Wert (die CLR kann oder nicht konvertieren Null in 0 in der Besetzung Operation)

Kein Duplikat von this question

Antwort

5

Sie vermeiden könnte die Frage:

char* foo = (char*)(void*)0; 
char* bar = default(char*); // <======= the one to look at 
Console.WriteLine(foo == bar); // writes True 

So sind sie gleich, aber default mit vermeidet jede Annahme oder böse Abgüsse in den Code eingebettet werden müssen. Auseinanderbauen der oben ist der einzige Unterschied mit/ohne Vorzeichen - beide mit einem 4-Byte-Konstante starten (i4/u4) gegossen dann auf native-int (i/u) (die // Kommentare sind mir):

.maxstack 2 
.locals init (
    [0] char* foo, 
    [1] char* bar) 
L_0000: ldc.i4.0 // (char*)(void*)0; 
L_0001: conv.i 
L_0002: stloc.0 // foo= 
L_0003: ldc.i4.0 // default(char*); 
L_0004: conv.u 
L_0005: stloc.1 // bar= 
L_0006: ldloc.0 
L_0007: ldloc.1 
L_0008: ceq // foo == bar 
L_000a: call void [mscorlib]System.Console::WriteLine(bool) 
+0

Ah yeh, ich habe vergessen, dass Standard auf Zeiger funktioniert. Das ist eine schöne Lösung. – Eloff

0

In C ist NULL als architekturspezifisch definiert. Während die meisten Architekturen 0 verwenden, tun einige nicht. So kann man nicht davon ausgehen, dass NULL == 0 in C.

Nicht ganz sicher, wie es in C# funktioniert, obwohl ich empfehlen würde, dass Sie auf die übliche Weise bleiben von NULL in C# Angabe, anstatt es von Gießen auf 0

+0

Wie lautet die Standardmethode zum Angeben von null für Zeiger in C#? Ich habe beide gesehen und Casting 0 scheint häufiger zu sein. Ich mag null, weil es lesbarer ist, aber die Entscheidung darüber, was zu verwenden ist, hängt von der Antwort ab, ob sie gleichwertig sind oder nicht. – Eloff