2011-07-13 10 views
12

la compilación de este fragmento de código con gcc (4,5) y otros tantos -Wall, -Wextra, banderas de tipo -Wuninitialized enciende posible me da ninguna advertencia:¿Es esto válido C? Sin advertencia sobre p siendo desinicializar

int main() { 
    int *p = p; 
    printf("p = %p\n", (void *)p); 
    return 0; 
} 

Pero se ejecutan múltiples veces da esta salida:

p = 0xbe9ff4 
p = 0x550ff4 
p = 0xeb1ff4 
p = 0x4caff4 

... y así sucesivamente.

¿Qué está pasando aquí?

EDIT: Compilar con "g ++ -Wall" en lugar me da aviso que yo esperaría:

In function ‘int main()’: warning: ‘p’ is used uninitialized in this function 
+0

Parece que ha engañado al compilador ... – vines

+0

Lo he visto antes en alguna parte. No sé si es un comportamiento válido, pero seguramente indefinido. – Marlon

+0

Llamar a una función que acepta una cantidad variable de argumentos sin un prototipo en el ámbito es UB. Tu compilador puede hacer lo que quiera – pmg

Respuesta

11
int *p = p; 

p se define como antes int *p se analice, pero el lado derecho está a sólo evaluado después. Esta afirmación es equivalente a

int * p; 
p = p; 

Esto es diferente en C++ con constructores implícitas, pero en ol llano' C, esto es lo que tienes. Valor inicial indefinido.

En lo que respecta a la advertencia del compilador, se trata de un problema de calidad de implementación. gcc no está siendo "engañado", solo es permisivo.

+0

Tiene razón, pero si divido la declaración en dos líneas como sugiere, I * do * recibe la advertencia. – akent

+6

Entonces, hay una brecha en la lógica de advertencia de gcc. Presente un informe de error. – spraff

+0

Sin embargo, no es obligatorio que un compilador encuentre todas las advertencias posibles. –

2

Valgrind emite advertencias sobre p que no está inicializado. Supongo que se engaña a gcc y se debe completar un informe de error.

+0

Felicitaciones a Valgrind por tener una prueba para eso, pero no estoy seguro de que me interese un informe de errores de gcc ..... – Soren

+0

@Soren: ¿Por qué no? –

+1

Supongo que no hay razón para no hacerlo. Solo estoy pensando que este es un caso de esquina demasiado pequeño para escribir código adicional ... – Soren

Cuestiones relacionadas