Ir para conteúdo

Isso *NÃO* é C


fredericopissarra

Posts Recomendados

Vejo, por ai, uma galera que escreve declarações de funções que não tomam argumentos como:

int main() { ... }

Só para lembrar: Segundo as especificações ISO 9989:1990 até ISO 9989:2011, isso ai não deveria ser feito. A declaração de função sem argumentos deve ser declarada como:

int main( void ) { ... }

Com esse void ai...

A lista de parâmetros vazia funciona graças à compatibilidade com o padrão K&R, que ainda é mantida em algum grau... Mas, o significado é indefinido (undefined behavior)... Normalmente a lista vazia significa que você pode passar qualquer número e tipos de argumentos e o compilador ignorará... Por exemplo:

int f() { return 1; }
...
f(1, "fred", NULL, &x, 0.0f ); // todos serão ignorados.

Qual é o problema? Em compiladores que não otimiza o código e usa a pilha, esses argumentos serão empilhados sem reclamação, mas a função jamais os usará...

Além disso, o ISO 9989 recomenda que a declaração ao estilo de C++ (argumentos vazios) não seja usada.

Link para o comentário
Compartilhar em outros sites

Antes de conhecer o curso do papo binário no youtube, eu estava "estudando" C por esse livro gratuito aqui:

http://icube-icps.unistra.fr/img_auth.php/d/db/ModernC.pdf 

que usa o void... E também fiquei usando por questão de clareza. Bom, não terminei de ler o livro, preferi fazer o curso do papo binário, mas não vi nesse livro 

nenhuma explicação do porquê de usar int main(void). Bom que agora estou sabendo, obrigado!

 

 

Link para o comentário
Compartilhar em outros sites

Ahhh... sim.. se formos obedecer à risca a especificação ISO 9989, o protótipo de main deve sempre ser:

int main( int argc, char *argv[] ); // ou esse...
int main( int argc, char **argv ); // ou esse, que é a mesma coisa!

O nome dos argumentos pode ser qualquer um (count e args, por exemplo). O nome só é importante quando há um protótipo que force a definição (por isso não costumo prototipar com nomes de argumentos).

No entanto, se sua função main não manipula os argumentos, ela pode ser declarada com uma lista de argumentos void. Mas, isso não é padrão!

PS: O tipo de retorno, pelo padrão deve sempre ser int, mas você pode declarar como void se não estiver mesmo interessado no "errorlevel"... Mas, isso também não faz parte do padrão...

Do ponto de vista do linker e co crt0.o (C Runtime object file - que é linkado junto com seu código), tudo o que interessa é o símbolo "main"... Já que, no padro de chamada cdecl quem manipula a pilha é o chamador, se main() receber ou não argumentos pela pilha, quem vai "limpá-la" é o crt0.o...

Link para o comentário
Compartilhar em outros sites

PS2: O ponteiro para a lista de ponteiros para strings das variáveis de ambiente (envp) não é padrão ISO 9989... Algumas implementações aceitam:

int main( int argc, char *argv[], char *envp[] );

Mas, prefira usar a função getenv() para obter o ponteiro envp acima, ao invés de usar essa declaração não padronizada (getenv() é definida no padrão POSIX).

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...