¿Está &*NULL bien definido en C?
language-lawyer (1)
¿En qué versión (s) de las normas C (si las hay) están bien definidas las siguientes?
void foo(void) {
char *nullPtr = NULL;
&*nullPtr;
}
Tenga en cuenta que no estoy asignando el resultado a nada: la segunda línea es una declaración simple.
Esta debería ser una pregunta con una respuesta obvia, pero (como parece suceder demasiado a menudo en esas preguntas) he escuchado que muchas personas dicen que la respuesta es "obviamente indefinida" como "obviamente definida".
En una nota más bien relacionada, ¿qué pasa con lo siguiente? ¿ foo
debería producir una lectura de c?
extern volatile char c;
void bar(void) {
volatile char *nonnullptr = &c;
&*nonnullptr;
}
(Versión de C ++ de la misma pregunta: ¿Está & * NULL bien definido en C ++? )
Si bien los intentos de anular la referencia a un puntero nulo causan un comportamiento indefinido, por lo que *nullPtr
es ilegal, &*nullPtr
está perfectamente bien definido. Según la nota de pie de página 102 en el Proyecto de Norma C11 :
Por lo tanto, & * E es equivalente a E (incluso si E es un puntero nulo), ...
Esto es un resultado del hecho de que, para el operador unario &
( §6.5.3.2 ¶3 ):
Si el operando es el resultado de un operador unario * , ni ese operador ni el operador & se evalúan y el resultado es como si ambos se omitieran, ...
El estándar C99 tiene el mismo lenguaje, pero esto no aparece en el estándar C90, y mi lectura de ese estándar es que &*nullPtr
podría causar un comportamiento indefinido en las implementaciones anteriores a C99.
De la norma C90 (§6.3.2.3):
El resultado del operador unario & (dirección-de) es un puntero al objeto o función designado por su operando ...
y:
El operador unario * denota la dirección indirecta ... Si se ha asignado un valor no válido al puntero, el comportamiento del operador unario * no está definido.
Curiosamente, no veo ninguna discusión de este cambio en la Razón C99 , aunque es posible que simplemente no lo encuentre.