¿Se requiere / define NULL en C para que sea cero?

NULL parece ser cero en mis progtwigs de prueba de GCC, pero la wikipedia dice que NULL solo es necesario para apuntar a la memoria no direccionable.

¿Los comstackdores hacen que NULL distinto de cero? Tengo curiosidad por saber if (ptr == NULL) es una mejor práctica que if (!ptr) .

Se garantiza que NULL es cero, tal vez con el (void *) 1 .

C99, §6.3.2.3, ¶3

Una expresión constante entera con el valor 0 , o una expresión de este tipo para escribir void * , se llama constante de puntero nulo. (55) Si una constante de puntero nulo se convierte en un tipo de puntero, el puntero resultante, llamado puntero nulo, está garantizado para comparar desigual a un puntero a cualquier objeto o función.

Y la nota 55 dice:

55) La macro NULL se define en (y otros encabezados) como una constante de puntero nulo.

Observe que, debido a la forma en que se formulan las reglas para punteros nulos, se garantiza que el valor que utiliza para asignar / comparar punteros nulos es cero, pero el patrón de bits realmente almacenado dentro del puntero puede ser cualquier otra cosa (pero AFAIK solo unos pocos muy las plataformas esotéricas explotaron este hecho, y esto no debería ser un problema de todos modos ya que para “ver” el patrón de bits subyacente debes ingresar a UB -y de todos modos).


Entonces, en lo que respecta al estándar, las dos formas son equivalentes ( !ptr es equivalente a ptr==0 debido a §6.5.3.3 ¶5, y ptr==0 es equivalente a ptr==NULL ); if(!ptr) también es bastante idiomático.

Dicho esto, normalmente escribo explícitamente if(ptr==NULL) lugar de if(!ptr) para dejar más claro que estoy comprobando la nulidad de un puntero en lugar de algún valor booleano.


  1. Tenga en cuenta que en C ++ el molde void * no puede estar presente debido a las reglas de conversión implícitas más estrictas que harían engorroso el uso de dicho NULL (tendría que convertirlo explícitamente al tipo del puntero comparado cada vez).

Desde el estándar de lenguaje:

6.3.2.3 Punteros

3 Una expresión constante entera con el valor 0, o una expresión de este tipo para escribir void * , se llama constante de puntero nulo . 55) Si una constante de puntero nulo se convierte en un tipo de puntero , se garantiza que el puntero resultante, llamado puntero nulo , se compare desigual a un puntero a cualquier objeto o función.

55) La macro NULL se define en (y otros encabezados) como una constante de puntero nulo; ver 7.17.

Dado ese lenguaje, la macro NULL debe evaluar a una expresión de valor cero (un literal 0 no decorado, una expresión como (void *) 0 , u otra macro o expresión que finalmente evalúa a 0). Las expresiones ptr == NULL y !ptr deben ser equivalentes. La segunda forma tiende a ser un código C más idiomático.

Tenga en cuenta que el valor del puntero nulo no tiene que ser 0. La implementación subyacente puede usar cualquier valor que desee para representar un puntero nulo. En lo que respecta a su código fuente, sin embargo, una expresión de puntero de valor cero representa un puntero nulo.

En la práctica es lo mismo, pero NULL es diferente a cero. Como cero significa que hay un valor y NULL significa que no hay ninguno. Entonces, teóricamente son diferentes, NULL tiene un significado diferente y en algunos casos esa diferencia debería ser de alguna utilidad.

en la práctica, no,! ptr es correcto