"Int main (vooid)"? ¿Cómo funciona?

135

Recientemente tuve que escribir un pequeño programa de prueba C y, en el proceso, cometí un error de ortografía en la función principal al usar accidentalmente en vooidlugar de void.

Y aún así funcionó.

Reduciéndolo a su versión completa más pequeña, terminé con:

int main (vooid) {
    return 42;
}

De hecho, esto compila ( gcc -Wall -o myprog myprog.c) y, cuando se ejecuta, devuelve 42.

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


Aquí hay una transcripción cortada y pegada de mi bashshell 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
paxdiablo
fuente
Al definir main con un solo intparámetro, invocas Comportamiento indefinido . Cualquier cosa puede pasar :)
pmg
9
En realidad, no estoy seguro acerca de la UB, @pmg. ISO específicamente permite otras posibilidades de mainlos dos estándares canónicos. Para la portabilidad, debe usar uno de esos dos, pero no creo que UB se aplique aquí.
paxdiablo
Hmm: en un entorno alojado maindebe tener una de las 2 formas canónicas (2.1.2.2). Pero tiene razón @pax, en un entorno independiente, el identificador no maines de ninguna manera especial: si se usa como una función, puede ser de cualquier tipo y tener cualquier número de parámetros de cualquier tipo.
pmg
2
En C99, la implementación independiente está totalmente definida. Para el host, la sección 5.1.2.2.1 establece al final "o de alguna otra manera definida por la implementación", por lo que requiere, como mínimo, las dos formas canónicas, pero también puede tener otras (esto permitiría que UNIXy int main (int argc, char *argv[], char *envp[]);se ajuste )
paxdiablo

Respuestas:

220

Simplemente está usando la sintaxis de declaración de función "estilo antiguo"; estás declarando implícitamente un intparámetro llamado vooid.

Oliver Charlesworth
fuente
2
Este parece ser el caso. Si agrega "vooid = 42; return vooid;" a main, también obtienes un valor de retorno de 42.
Jeff Ames
43
Aargghh, tienes razón. Si agrego -std=c99, obtengo qq.c:1: warning: type of 'vooid' defaults to 'int'.
paxdiablo
70

Es un 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
} 

vooidcontiene uno más el número de argumentos pasados ​​(es decir, argc). Así que, en efecto, todo lo que hemos hecho es cambiar el nombre argca vooid.

Michael Goldshteyn
fuente
11
Si haces "regresar vooid"; en cambio, de hecho da 1 + num. de args.
Jeff Ames
66
@Jeff, el nombre del programa se cuenta como un argumento, de ahí el + 1
Martin Beckett
23

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

Chinmay Kanchi
fuente
20

Es único gcc -std=c89 -Wall -o qq qq.cy gcc -std=gnu89 -Wall -o qq qq.cno emite una advertencia. Todos los demás estándares emiten una advertencia sobre el tipo implícito intpara vooid.

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

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

Probé con gcc 4.4.5 en el sistema de prueba de Debian.

vpit3833
fuente