2015-02-06 7 views
13

Ich habe die C# -Sprachspezifikation durchsucht und kann nichts finden, das angibt, ob ein Zeigertyp (z. B. int*) mit einem Standardwert initialisiert wird. Ich habe eine einfache Test-App erstellt und sie scheint sie auf Null zu initialisieren, aber ich möchte dies mit der Spezifikation bestätigen.C# Standardwert eines Zeigertyps

Ich begann dafür suchen, weil ich in Reflektor bemerkte die IntPtr Klasse diesen Code verwendet, um seine definieren IntPtr.Zero:

public struct IntPtr : ISerializable 
{ 
    private unsafe void* m_value; 
    public static readonly IntPtr Zero; 

    ....... 

    public static unsafe bool operator ==(IntPtr value1, IntPtr value2) 
    { 
     return (value1.m_value == value2.m_value); 
    } 

    ........ 
} 

was bedeutet, dass, wenn Sie gegen IntPtr.Zero vergleichen sie tatsächlich gegen den Standardwert vergleicht zugewiesen das Feld m_value mit dem Typ void*.

Danke.

+1

Es gibt Teile der Spezifikation, die Zeiger diskutieren, die diskutieren, wie sie mit der Analyse definierter Zuordnung interagieren. Wenn man bedenkt, dass der Hauptzweck einer bestimmten Zuweisungsanalyse darin besteht, zu vermeiden, dass Sie einen nicht initialisierten Zustand einer Variablen beobachten, lautet die Antwort möglicherweise Mu. Außerdem ist nicht alles, was Sie bei der Implementierung von Framework-Typen sehen, die ganze Geschichte - manchmal erzeugt eine spezielle Behandlung durch die Runtime das tatsächliche Verhalten. –

+0

Gut gefleckt ... sieht aus, als hätten sie es beim Schreiben der Spezifikation verpasst. Man kann annehmen, dass es null (null) ist :-) – buffjape

+0

Was verwirrend ist, ist, dass CIL Zeigertypen als Teilmenge von Referenztypen definiert, aber C# definiert Zeigertypen als eigenständige Klasse von Typen. Wenn CIL angibt, dass Referenztypen den Standardwert "null" haben, bedeutet das mehr als wenn C# dasselbe angibt. – hvd

Antwort

-1

Mit dem Visual Studio-Debugger können Sie den Standardwert einem int-Zeiger zuweisen. In einer 32-Bit-Architektur ist es 0x00000000 (32 0 Bits).

class Program 
{ 
    private static unsafe int* m_value; 
    static void Main(string[] args) 
    { 
    } // <<== Break point here 
} 

Watch Window 
_____________________________________________ 
Name Value  Type 
======= ========== ======== 
m_value 0x00000000 int* 
+2

Ja, wie ich schon sagte, ich habe eine Test-App geschrieben, die das tat, aber das bedeutet nicht unbedingt, dass der Wert immer Null ist (es könnte einfach Glück sein). – user3784392

+3

Die C# -Spezifikation definiert den defualt-Wert für einen Zeiger sehr sorgfältig nicht. – Rawling

1

Ich glaube, Zeiger haben keinen Standardwert; weil der Wert eines Zeigers die Adresse eines Teils des Speichers ist, der etwas enthält, dem Sie ihn zuweisen. Wenn Sie es nicht zugewiesen haben, könnte es auf etwas im Speicher zeigen.

Vielleicht ist das Standardverhalten der CLR, es auf IntPtr.Zero zu setzen, die "einen Zeiger oder ein Handle darstellt, der auf Null initialisiert wurde", was wahrscheinlich aus Carmelo Floridias Antwort zu stammen scheint. Dies scheint ein Implementierungsdetail zu sein, auf das die Spezifikation möglicherweise nicht eingegangen ist.

1

Der Standardwert der Zeigertypen nach Spezifikationen ist null. Dies folgt aus zwei Fakten.

Erste Tatsache ist, dass Zeiger Referenztyp ist. Es wird in ECMA-335 beschrieben: enter image description here

Zweiter Fakt ist, dass reference-type has default value - null.

+0

'Type.IsClass' auf Zeigern ist' true', aber 'default (typeof (void *))' ist 'IntPtr.Zero', nicht null. Beide Referenztypen haben keinen Standardwert als 'null' * immer * oder Zeiger ist kein Referenztyp. Ich glaube, es ist Ersteres. – nawfal

+0

@nawfal 'IntPtr.Zero' wird standardmäßig initialisiert. Das erste Feld 'IntPtr.Zero' ist' private unsafe void * m_value'. Wenn 'void * m_value'' IntPtr.Zero' ist, dann haben wir Ähnlichkeit der Rekursion. –