8

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

在 C# 中,您可以将 null 或 (T*)0 分配给不安全代码中的指针。

  1. 有什么区别吗?
  2. (long)(void*)0 == 0 (保证与否?换句话说:IntPtr.Zero.ToInt64() == 0)

MSDN 对 IntPtr.Zero 有这样的说法:

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

不是这个问题的重复

4

2 回答 2

5

你可以避免这个问题:

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

所以它们是相同的,但使用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)
于 2010-05-05T04:27:48.787 回答
0

在 C 中,NULL被定义为体系结构特定的。虽然大多数体系结构使用 0,但有些不使用。所以,你不能假设NULL == 0在 C 中。

不太确定它在 C# 中是如何工作的,但我建议您坚持NULL在 C# 中指定的标准方式,而不是将其强制转换为 0。

于 2010-05-05T01:05:58.237 回答