Jump to content
Sign in to follow this  
fredericopissarra

Isso *NÃO* é C

Recommended Posts

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.

  • Curtir 1
  • l33t 2

Share this post


Link to post
Share on other 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!

 

 

  • Agradecer 1

Share this post


Link to post
Share on other 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...

Share this post


Link to post
Share on other 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).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...