指针类型的C#默认值

问题描述:

我一直在搜索C#语言规范,找不到指针类型(例如int*)是否使用默认值初始化的任何内容。我创建了一个简单的测试应用程序,它似乎将它们初始化为零,但我想用规范来确认它。指针类型的C#默认值

我开始寻找这一点,因为我在反光注意到IntPtr类使用这个代码来定义其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); 
    } 

    ........ 
} 

这意味着,当你比较反对IntPtr.Zero它实际上是对分配到默认值进行比较m_value字段,其​​类型为void*

谢谢。

+1

有一些规范的讨论指针,讨论它们如何与明确的赋值分析交互。考虑到明确赋值分析的要点是为了避免你观察变量的未初始化状态,也许答案是Mu。此外,并非所有在框架类型实现中看到的都是完整的故事 - 有时运行时的特殊处理会产生实际行为。 – 2015-02-06 13:46:52

+0

看起来好像他们在写规格时错过了它。猜你可以认为它是零(空):-) – buffjape 2015-02-06 14:06:47

+0

令人困惑的是,CIL将指针类型定义为引用类型的一个子集,但C#将指针类型定义为不同的类类型。因此,当CIL指定引用类型具有默认值'null'时,这意味着比C#指定相同的东西更多。 – hvd 2015-02-07 15:09:15

使用Visual Studio调试器,您可以获取分配给int指针的默认值。在32位体系结构中,它是0x00000000(32 0位)。

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

是的,正如我所说我写了一个测试应用程序这样做,但这并不一定意味着价值将永远是零(它可能只是运气)。 – user3784392 2015-02-06 14:18:30

+3

C#规范非常小心地不定义指针的默认值。 – Rawling 2015-02-06 14:32:32

我相信指针没有默认值;由于指针的值是包含您分配的内容的一部分内存的地址。如果你还没有分配它,它可能指向内存中的任何东西。

也许CLR的默认行为是将其设置为IntPtr.Zero,其中“表示已初始化为零的指针或句柄”,看起来很可能来自Carmelo Floridia的答案。这似乎是该规范可能没有详细阐述的实现细节。

按规格指针类型的默认值为null。这是从两个事实。

第一个事实是,指针是参考类型。它描述于ECMA-335enter image description here

第二个事实是reference-type has default value - null

+0

指针上的Type.IsClass是'true',但是'default(typeof(void *))'是'IntPtr.Zero',不是null。任何引用类型都没有默认值,因为'null' * always *或指针不是引用类型。我相信这是前者。 – nawfal 2016-07-05 14:31:35

+0

@nawfal默认初始化为'IntPtr.Zero'。第一个字段'IntPtr.Zero'是'private unsafe void * m_value'。如果'void * m_value'是'IntPtr.Zero',那么我们有递归的相似性。 – 2016-07-06 18:47:24