2010-05-05 6 views
8

Esto puede parecer extraño, pero en C (size_t) (void *) 0 == 0 no está garantizado por la especificación del idioma. Los compiladores pueden usar cualquier valor que deseen para nulo (aunque casi siempre usan 0.)¿Hay alguna diferencia entre nulo y 0 al asignar punteros a un código inseguro?

En C#, puede asignar nulo o (T *) 0 a un puntero en código inseguro.

  1. ¿Hay alguna diferencia?
  2. (largo) (void *) 0 == 0 (garantizados o no dicho de otra manera:? IntPtr.Zero.ToInt64() == 0)

MSDN tiene esto que decir acerca de IntPtr. Cero:

"El valor de este campo no es equivalente a nulo". Bueno, si quieres ser compatible con el código C, tiene mucho sentido, sería inútil para la interoperabilidad si no se convirtiera en un puntero C nulo. Pero quiero saber si IntPtr.Zero.ToInt64() == 0 que puede ser posible, incluso si internamente IntPtr.Zero es algún otro valor (el CLR puede o no convertir nulo a 0 en la operación de conversión)

No es un duplicado de this question

Respuesta

5

Usted podría evitar el problema:

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

por lo que son los mismos, pero utilizando default evita tener que incorporar algún supuesto o moldes desagradables en el código. Desmontaje de lo anterior, la única diferencia es firmado/sin firmar - tanto a empezar con una constante de 4 bytes (i4/u4) y luego echado al nativo-int (i/u) (los // comentarios son míos):

.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

Ah, sí, olvidé que el valor predeterminado funciona en los punteros. Esa es una buena solución. – Eloff

0

En C, NULL se define como arquitectura específica. Mientras que la mayoría de las arquitecturas usan 0, otras no. Por lo tanto, no se puede asumir que NULL == 0 en C.

No estoy seguro de cómo funciona en C# aunque recomendaría que se adhieren a la forma estándar de especificar NULL en C# en lugar de echar a 0.

+0

¿Cuál es la forma estándar de especificar null para los punteros en C#? He visto ambos usados ​​y el lanzamiento de 0 parece ser más común. Me gusta nulo porque es más legible, pero la decisión sobre qué usar realmente depende de si son equivalentes o no. – Eloff

Cuestiones relacionadas