Jump to content

Isso *NÃO* é C


fredericopissarra

Recommended Posts

Posted

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.

Posted

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!

 

 

Posted

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...

Posted

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).

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...