"Int main (vooid)"? Como isso funciona?

135

Recentemente, tive que digitar um pequeno programa de teste C e, no processo, cometi um erro de ortografia na função principal usando acidentalmente em vooidvez de void.

E ainda assim funcionou.

Reduzindo-o para a menor versão completa, acabei com:

int main (vooid) {
    return 42;
}

Isso de fato compila ( gcc -Wall -o myprog myprog.c) e, quando executado, retorna 42.

Como exatamente esse código é válido?


Aqui está uma transcrição recortada e colada do meu bashshell para mostrar o que estou fazendo:

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

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

pax$ echo $?
42
paxdiablo
fonte
Ao definir main com um único intparâmetro, você invoca o comportamento indefinido . Qualquer coisa pode acontecer :)
pmg
9
Na verdade, não tenho certeza sobre o UB, @pmg. A ISO permite especificamente outras possibilidades maindesde as duas canônicas padrão. Para portabilidade, você deve usar um desses dois, mas acho que o UB não se aplica aqui.
21411
Hmm: em um ambiente hospedado, maindeve ter uma das 2 formas canônicas (2.1.2.2). Mas você está certo @pax, em um ambiente independente, o identificador não mainé de forma alguma especial: se usado como uma função, pode ser de qualquer tipo e ter qualquer número de parâmetros de qualquer tipo.
pmg 14/02
2
No C99, o autônomo é totalmente definido pela implementação. Para hospedado, a seção 5.1.2.2.1 declara no final "ou de alguma outra maneira definida pela implementação", pelo que requer, no mínimo, as duas formas canônicas, mas também pode ter outras (isso permitiria que o UNIXy int main (int argc, char *argv[], char *envp[]);estivesse em conformidade )
21411

Respostas:

220

É simplesmente usar a sintaxe de declaração de função "estilo antigo"; você está declarando implicitamente um intparâmetro chamado vooid.

Oliver Charlesworth
fonte
2
Este parece ser o caso. Se você adicionar "vooid = 42; return vooid;" a principal, você também terá um valor de retorno de 42.
Jeff Ames
43
Aargghh, você está certo. Se eu adicionar -std=c99, eu entendo qq.c:1: warning: type of 'vooid' defaults to 'int'.
22411
70

É um código válido, porque myprog.c contém:

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

vooidcontém um mais o número de argumentos passados ​​(ou seja, argc). Então, na verdade tudo o que tenho feito é mudar o nome argcpara vooid.

Michael Goldshteyn
fonte
11
Se você "retornar vazio"; em vez disso, de fato, fornece 1 + num. de args.
Jeff Ames
6
@ Jeff, o nome do programa é contado como argumento, daí a + 1
Martin Beckett
23

Em C, o tipo padrão para um argumento de função é int. Portanto, seu programa está tratando a palavra vooidcomo int main(int vooid), que é um código perfeitamente válido.

Chinmay Kanchi
fonte
20

É apenas gcc -std=c89 -Wall -o qq qq.ce gcc -std=gnu89 -Wall -o qq qq.cnão emite um aviso. Todos os outros padrões emitem um aviso sobre o tipo implícito intpara vooid.

int main(chart)se comporta da mesma maneira que faz int main (vooid).

return vooid; retorna o número de argumentos da linha de comando.

Testei com o gcc 4.4.5 no sistema de teste Debian.

vpit3833
fonte