在分配给不安全代码中的指针时,null和0之间有什么区别吗?

Elo*_*off 8 c# unsafe

这可能看起来很奇怪,但在C(size_t)(void*)中,语言规范不保证0 == 0.允许编译器使用他们想要的任何值为null(尽管它们几乎总是使用0).

在C#中,您可以为不安全代码中的指针指定null或(T*)0.

  1. 有什么区别吗?
  2. (长)(void*)0 == 0(保证与否?换另一种方式:IntPtr.Zero.ToInt64()== 0)

关于IntPtr.Zero,MSDN有这个说法:

"该字段的值不等于null." 好吧,如果你想与C代码兼容,这很有意义 - 如果没有转换为C空指针,它对于互操作是没有价值的.但是我想知道IntPtr.Zero.ToInt64()== 0是否可能,即使内部IntPtr.Zero是其他一些值(在转换操作中CLR可能会也可能不会将null转换为0)

不是这个问题的重复

Mar*_*ell 5

你可以避免这个问题:

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

所以它们是相同的,但使用default避免必须在代码中嵌入任何假设或讨厌的强制转换.反汇编以上,唯一的区别是有符号/无符号 - 都以4字节常量(i4/ u4)开头,然后转换为native-int(i/ u)(//注释是我的):

.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)
Run Code Online (Sandbox Code Playgroud)