Есть ли разница между нулем и 0 при назначении указателей в небезопасном коде? - PullRequest
8 голосов
/ 05 мая 2010

Это может показаться странным, но в C (size_t) (void *) 0 == 0 не гарантируется спецификацией языка. Компиляторам разрешено использовать любое значение, которое они хотят для нуля (хотя они почти всегда используют 0.)

В C # вы можете присвоить нулевой или (T *) 0 указателю в небезопасном коде.

  1. Есть ли разница?
  2. (long) (void *) 0 == 0 (гарантировано или не? Перефразируй: IntPtr.Zero.ToInt64 () == 0)

В MSDN есть это, чтобы сказать о IntPtr.Zero:

"Значение этого поля не эквивалентно нулю." Хорошо, если вы хотите быть совместимым с кодом на C, это имеет большой смысл - было бы бесполезно для взаимодействия, если бы оно не конвертировалось в нулевой указатель на C. Но я хочу знать, возможно ли IntPtr.Zero.ToInt64 () == 0, даже если внутренне IntPtr.Zero является каким-то другим значением (CLR может или не может преобразовать ноль в 0 в операции приведения)

Не дубликат этого вопроса

Ответы [ 2 ]

5 голосов
/ 05 мая 2010

Вы можете избежать проблемы:

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)
0 голосов
/ 05 мая 2010

В C NULL определяется как специфичная для архитектуры. В то время как большинство архитектур используют 0, некоторые нет. Таким образом, вы не можете предположить, что NULL == 0 в C.

Не совсем уверен, как это работает в C #, хотя я бы порекомендовал вам придерживаться стандартного способа указания NULL в C # вместо приведения его к 0.

...