¿Se requiere/definió NULL en C como cero?

4 minutos de lectura

avatar de usuario
voluntad

NULL parece ser cero en mis programas de prueba de GCC, pero wikipedia dice que NULL solo se requiere para apuntar a la memoria no direccionable.

¿Algún compilador hace NULL distinto de cero? tengo curiosidad si if (ptr == NULL) es una mejor práctica que if (!ptr).

avatar de usuario
Mateo Italia

NULL está garantizado que es cero, quizás convertido a (void *)1.

C99, §6.3.2.3, ¶3

Una expresión constante entera con el valor 0o tal expresión convertida para escribir
void *se denomina 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 comparará con un puntero a cualquier objeto o función.

Y la nota 55 dice:

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

Tenga en cuenta que, debido a cómo se formulan las reglas para los punteros nulos, se garantiza que el valor que usa 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, debe ingresar UB-tierra 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, suelo escribir explícitamente if(ptr==NULL) en 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. Observe que en C++ el void * cast no puede estar presente debido a las reglas de casting implícitas más estrictas que harían el uso de tal NULL engorroso (tendría que convertirlo explícitamente al tipo de puntero comparado cada vez).

  • Sin embargo, no es necesario que los bytes de un puntero nulo sean ceros.

    – Aschepler

    27 de noviembre de 2011 a las 19:57

  • @aschepler: ¿y qué escribí en mi respuesta?

    – Mateo Italia

    27 de noviembre de 2011 a las 19:58

  • comentario fue sobre una revisión anterior. buena respuesta.

    – Aschepler

    27 de noviembre de 2011 a las 20:05

  • El punto más importante para llevar a casa: void *p; memset(&p, 0, sizeof p); no hace p a NULO puntero.

    – Simón Richter

    28 de noviembre de 2011 a las 12:37


  • @SimonRichter: No necesariamente hacer p un puntero nulo. (Es muy probable que lo haga en la mayoría de los sistemas, pero dependiendo de eso, su código no es portátil).

    –Keith Thompson

    30 de noviembre de 2011 a las 5:32

avatar de usuario
Juan Bode

Del 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 convertida al tipo
void *se llama un constante de puntero nulo.55) Si una constante de puntero nulo se convierte en un tipo de puntero, el puntero resultante, denominado puntero nuloestá garantizado para comparar desigual a un puntero a cualquier objeto o función.

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

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

Tenga en cuenta que el puntero nulo valor no tiene que ser 0. La implementación subyacente puede usar cualquier valor que desee para representar un puntero nulo. Sin embargo, en lo que respecta a su código fuente, 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. Dado que 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.

  • Cercano, pero no del todo exacto. 0 es un valor de tipo int. NULL es un valor de tipo puntero. (Incluso eso es impreciso; NULL es una macro que se expande a un constante de puntero nulolo que produce un puntero nulo cuando se convierte a un tipo de puntero.)

    –Keith Thompson

    30 de noviembre de 2011 a las 15:52

en la práctica no, !ptr es correcto

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad