Me pregunto qué tipo es Null en C. Probablemente sea un duplicado, pero seguí obteniendo información sobre el tipo void en las búsquedas. Tal vez una mejor manera es ¿se puede devolver NULL para cualquier tipo de función? Por ejemplo:
int main(){
dosomething();
return NULL;
}
¿Eso funciona?
El tipo de NULL
puede ser de tipo entero o void *
. Esto se debe a que el estándar C permite que se defina como una expresión constante entera o como el resultado de una conversión a void *
.
C 2018 7.19 3 dice NULL
“se expande a una constante de puntero nulo definida por la implementación” (cuando se ha incluido alguno de varios encabezados: <locale.h>
, <stddef.h>
, <stdio.h>
, <stdlib.h>
, <string.h>
, <time.h>
o <wchar.h>
).
C 6.3.2.3 3 dice que una constante de puntero nulo es “Una expresión constante entera con el valor 0, o una expresión de este tipo convertida en un tipo void *
.”
Por lo tanto, una implementación de C puede definir NULL
como por ejemplo:
0
que tiene tipo int
,
((void *) 0)
que tiene tipo void *
o
(1+5-6)
que es una expresión constante entera con valor 0 y tipo int
.
Aunque NULL
puede tener un tipo entero, puede compararse y asignarse a punteros, como en if (p == NULL) …
. Las reglas para estas operaciones dicen que un cero constante entero se convertirá en el tipo de puntero apropiado para la operación.
Aunque NULL
puede definirse como 0
, está destinado a ser utilizado para punteros, no como un cero entero. Los programas deben evitar hacer eso, y las implementaciones de C generalmente son mejores si lo definen como ((void *) 0)
para ayudar a evitar errores en los que podría aceptarse como un valor entero.
En la mayoría de las implementaciones de C, convertir NULL
a un entero dará cero. Sin embargo, esto no está garantizado en el estándar C. Está permitido que (int) NULL
o (uintptr_t) NULL
producirá la dirección de alguna ubicación especial “no usar” en lugar de cero. Incluso (int) (void *) 0
podría producir tal dirección en lugar de cero.
Cuando un cero constante entero se convierte en un tipo de puntero, la implementación de C lo trata de manera especial; produce un puntero nulo para esa implementación incluso si su puntero nulo usa una dirección distinta de cero. El hecho de que sea una constante entera significa que el compilador puede aplicar este tratamiento especial donde reconoce la conversión en el código fuente. Si tenemos alguna expresión no constante, como una int
variable x
luego (void *) x
no se garantiza que produzca un puntero nulo incluso si el valor de x
es cero
¿Qué tipo es NULL?
Respuesta corta: el tipo de NULL
es void*
o int
, long
, unsigned
…
Adición a la buena respuesta de @Eric Postpischil para señalar más trampas de codificación.
(macro) NULL
que se expande a una implementación definida constante de puntero nulo. C11dr §7.19 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. §6.3.2.3 3
los escribe de NULL
tiene muchas posibilidades dada la “constante entera”. El código portátil no debe asumir un tipo particular. NULL
se utiliza mejor en contextos de puntero.
// Poor code as NULL may not match the type of the specifier - undefined behavior
printf("%p\n", NULL); // poor
printf("%d\n", NULL); // poor
// Better
printf("%d\n", (int) NULL);
// Best. NULL is best used in a pointer context, print as a pointer
printf("%p\n", (void *) NULL);
cplusplus.com/reference/cstring/NULL
– Roberto Harvey
4 de febrero de 2014 a las 17:28
int
– está en la firma– wb
4 de febrero de 2014 a las 17:29
NULL
no existe en C. Probablemente estés usando algo como#define NULL 0
que debería responder a su pregunta.– SLaks
4 de febrero de 2014 a las 17:29
En C suele ser un
void *
es decir#define NULL ((void *)0)
. En C++ es solo0
.– Pablo R.
04/02/2014 a las 17:30
int
no es un puntero.– Roberto Harvey
04/02/2014 a las 17:31