Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any difference between null and 0 when assigning to pointers in unsafe code?

Tags:

c#

unsafe

This may seem odd, but in C (size_t)(void*)0 == 0 is not guaranteed by the language spec. Compilers are allowed to use any value they want for null (although they almost always use 0.)

In C#, you can assign null or (T*)0 to a pointer in unsafe code.

  1. Is there any difference?
  2. (long)(void*)0 == 0 (guaranteed or not? put another way: IntPtr.Zero.ToInt64() == 0)

MSDN has this to say about IntPtr.Zero:

"The value of this field is not equivalent to null." Well if you want to be compatible with C code, that makes a lot of sense - it'd be worthless for interop if it didn't convert to a C null pointer. But I want to know if IntPtr.Zero.ToInt64() == 0 which may be possible, even if internally IntPtr.Zero is some other value (the CLR may or may not convert null to 0 in the cast operation)

Not a duplicate of this question

like image 893
Eloff Avatar asked May 05 '10 00:05

Eloff


People also ask

Which is the operator that Cannot operate on pointers in an unsafe context?

The void* type represents a pointer to an unknown type. Because the referent type is unknown, the indirection operator cannot be applied to a pointer of type void* , nor can any arithmetic be performed on such a pointer.

Which type is used in unsafe mode?

Now to understand what UnsafeMode is. Unsafe is a C# programming language keyword to denote a section of code that is not managed by the Common Language Runtime (CLR) of the . NET Framework, or unmanaged code. Unsafe is used in the declaration of a type or member or to specify a block code.

What is unsafe code in C sharp?

Unsafe code in C# isn't necessarily dangerous; it's just code whose safety cannot be verified. Unsafe code has the following properties: Methods, types, and code blocks can be defined as unsafe. In some cases, unsafe code may increase an application's performance by removing array bounds checks.

What is unsafe code?

Unsafe code in general is a keyword that denotes a code section that is not handled by the Common Language Runtime(CLR). Pointers are not supported by default in C# but unsafe keyword allows the use of the pointer variables.


1 Answers

You could avoid the issue:

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

So they are the same, but using default avoids having to embed any assumption or nasty casts into the code. Disassembling the above, the only difference is signed / unsigned - both start with a 4-byte constant (i4 / u4) then cast to native-int (i / u) (the // comments are mine) :

.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)
like image 140
Marc Gravell Avatar answered Sep 25 '22 14:09

Marc Gravell