C#指针类型的默认值

13

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

我开始寻找这个问题是因为我注意到,在反编译器中,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。此外,您在框架类型实现中看到的并不是全部 - 有时运行时的特殊处理会产生实际的行为。 - Damien_The_Unbeliever
很好地发现了...看起来在编写规范时他们错过了它。我猜你可以假设它是零(null) :-) - user1023602
令人困惑的是,CIL将指针类型定义为引用类型的子集,但C#将指针类型定义为类型的不同类。因此,当CIL指定引用类型具有“null”的默认值时,这意味着比C#指定相同内容更多。 - user743382
3个回答

1

指针类型的默认值根据规范是null。这是基于两个事实。

第一个事实是指针是引用类型。它在ECMA-335中有描述: enter image description here

第二个事实是引用类型的默认值为null


指针上的 Type.IsClasstrue,但 default(typeof(void*))IntPtr.Zero,而不是 null。要么引用类型的默认值不是 null(始终如此),要么指针不是引用类型。我相信是前者。 - nawfal
@nawfal IntPtr.Zero 默认初始化。第一个字段 IntPtr.Zeroprivate unsafe void* m_value。如果 void * m_valueIntPtr.Zero,那么我们就有了递归的相似性。 - Evgeniy Mironov

1
我认为指针没有默认值;因为指针的值是指向包含你分配给它的内容的一部分内存的地址。如果你没有分配它,它可能指向内存中的任何东西。
也许CLR的默认行为是将其设置为IntPtr.Zero, 这代表“已初始化为零的指针或句柄”,这似乎很有可能来自Carmelo Floridia的答案。这似乎是规范没有详细阐述的实现细节。

-1

使用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
3
C#规范非常谨慎地未定义指针的默认值。 - Rawling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接