2011-02-13 10 views
129

Hace poco tuve que escribir un pequeño programa de prueba C y, en el proceso, cometí un error ortográfico en la función principal al usar accidentalmente vooid en lugar de void."int main (vooid)"? ¿Cómo funciona?

Y aún así funcionó.

La reducción se reduce a su más pequeña versión completa, que terminó con:

int main (vooid) { 
    return 42; 
} 

Esto hecho de compilación (gcc -Wall -o myprog myprog.c) y, cuando se ejecuta, devuelve 42.

¿Cómo es exactamente este código válido?


Aquí hay un corte de transcripción y pegado de mi concha bash para mostrar lo que estoy haciendo:

pax$ cat qq.c 
int main (vooid) { 
    return 42; 
} 

pax$ rm qq ; gcc -Wall -o qq qq.c ; ./qq 

pax$ echo $? 
42 
+0

Al definir main con un solo parámetro 'int', invoca ** Comportamiento no definido **. Todo puede pasar :) – pmg

+9

En realidad, no estoy seguro sobre el UB, @pmg. ISO específicamente permite otras posibilidades de 'main' a partir de las dos estándar canónicas. Para la portabilidad, debe usar uno de esos dos, pero no creo que UB aplique aquí. – paxdiablo

+0

Hmm: en un entorno alojado 'main' debe tener una de las 2 formas canónicas (2.1.2.2). Pero tiene razón @pax, en un entorno autónomo, el identificador 'main' no es de ninguna manera especial: si se usa como función, puede ser de cualquier tipo y tener cualquier cantidad de parámetros de cualquier tipo. – pmg

Respuesta

215

Se trata simplemente utilizando la sintaxis de la función de declaración de "viejo estilo"; está declarando implícitamente un parámetro int llamado vooid.

+2

Este parece ser el caso. Si agrega "vooid = 42; return vooid;" a main, también obtienes un valor de retorno de 42. –

+43

Aargghh, tienes razón. Si agrego '-std = c99', obtengo' qq.c: 1: warning: tipo de 'vooid' por defecto a 'int''. – paxdiablo

67

Es código válido, porque myprog.c contiene:

int main (vooid) // vooid is of type int, allowed, and an alias for argc 
{  
    return 42; // The answer to the Ultimate Question 
} 

vooid contiene uno más el número de argumentos pasados ​​(es decir, argc). Entonces, en realidad, todo lo que ha hecho es cambiar el nombre de argc a vooid.

+11

Si lo haces, "devuelve vooid"; en cambio, de hecho da 1 + num. de args. –

+6

@Jeff, el nombre del programa se cuenta como argumento, por lo tanto, el +1 –

23

En C, el tipo predeterminado para un argumento de función es int. Por lo tanto, su programa trata la palabra vooid como int main(int vooid), que es un código perfectamente válido.

19

Sólo gcc -std=c89 -Wall -o qq qq.c y gcc -std=gnu89 -Wall -o qq qq.c no emiten ninguna advertencia. Todos los demás estándares emiten una advertencia sobre el tipo implícito int para vooid.

int main(chart) se comporta de la misma manera que int main (vooid).

return vooid; devuelve el número de argumentos de línea de comando.

He probado con gcc 4.4.5 en el sistema de prueba de Debian.