代码之家  ›  专栏  ›  技术社区  ›  Eloff

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

  •  8
  • Eloff  · 技术社区  · 14 年前

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

    在C中,可以将空值或(t*)0分配给不安全代码中的指针。

    1. 有什么区别吗?
    2. (长)(无效*)0==0(保证或 不是吗?换一种方式: intptr.zero.toint64()=0)

    关于intptr.zero,msdn有这样的说法:

    “此字段的值不等于空值。”如果您希望与C代码兼容,这很有意义-如果不转换为C空指针,对interop来说就没有价值。但我想知道intptr.zero.toint64()==0,这可能是可能的,即使内部intptr.zero是其他值(clr在强制转换操作中可能会或可能不会将null转换为0)

    不是的副本 this question

    2 回复  |  直到 14 年前
        1
  •  5
  •   Marc Gravell    14 年前

    你可以避免这个问题:

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

    所以它们是相同的,但是使用 default 避免在代码中嵌入任何假设或令人讨厌的强制转换。分解以上内容,唯一的区别是有符号/无符号-都以4字节常量开头( i4 / u4 )然后强制转换为本机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)
    
        2
  •  0
  •   sybreon    14 年前

    在C中, NULL 定义为特定于体系结构。虽然大多数体系结构使用0,但有些不使用。因此,您不能假定 NULL == 0 在C.

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