paulo1205
(usa Ubuntu)
Enviado em 27/08/2016 - 23:32h
Por mera questão de compatibilidade com versões legadas do C.
As primeiras versões do C não exigiam a declaração de absolutamente todos os símbolos, e aceitava emitir código mesmo na ausência de todas as informações sobre dados e funções, às vezes assumindo implicitamente certas propriedades sobre eles, o que acabava nem sempre sendo verdadeiro, e frequentemente se tornava fonte de erros.
Quando o C foi padronizado, em 1989, instituíram-se as declarações que permitem deixar bem claros os tipos e as formas de uso de variáveis e funções. Contudo, para não provocar o rompimento automático de compatibilidade com código preexistente, os hábitos antigos seriam tolerados, e o histórico comportamento de fazer assunções sobre tipos de dados e quantidade de argumentos passados às funções também,
a não ser que o compilador fosse instruído a exigir adequação às novas formas padronizadas .
Com as revisões do padrão de 1999 e 2011, algumas formas pré-padronizadas se tornaram definitivamente obsoletas ou proibidas, tais como, por exemplo, assumir implicitamente que variáveis não declaradas têm tipo
int , que funções podem ser declaradas omitindo tipo de retorno (para que seja também subentendido como
int ) e a aceitação de chamada de funções que não foram declaradas.
ENTRETANTO, o
gcc , mesmo quando instruído a usar C99/C11, ainda é tolerante com alguns desses casos, mesmo com o padrão caracterizando-os literalmente como erros. Para que ele siga o padrão à risca, você precisa das opções de linha de comando
-Wall e
-pedantic-errors . Veja o que acontece quando eu mando compilar o seu programa assim.
$ gcc -std=c11 -Wall -pedantic -pedantic-errors x.c
x.c:1:1: error: return type defaults to ‘int’
main(){
^
x.c: In function ‘main’:
x.c:2:2: error: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
printf("Hello, World!\n");
^
$
Se em vez de “
-std=c11 ” eu tivesse dito “
-std=c89 ”, as linhas 1 e 2 dariam apenas
warnings , pois essas deduções implícitas já eram consideradas um estilo ruim pelo padrão de 1989, mas ainda eram toleradas.
$ gcc -std=c89 -Wall -pedantic -pedantic-errors x.c
x.c:1:1: warning: return type defaults to ‘int’ [-Wreturn-type]
main(){
^
x.c: In function ‘main’:
x.c:2:2: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
printf("Hello, World!\n");
^
x.c:3:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
$
(Por outro lado, como você pode ver, a versão de 1989 tem três mensagens de aviso, em vez de duas de erro da versão de 2011. Isso é porque a versão de 2011 tornou opcional o comando
return na função
main (), assumindo implicitamente o efeito de “
return 0; ” se o comando estiver faltando. Essa “colher de chá” -- da qual eu pessoalmente não gosto, porque introduz uma distinção artificiosa entre
main () e todas as demais funções, obrigando o compilador a adotar regras específicas apenas para essa função -- não existia no padrão de 1989, e isso explica a terceira mensagem.)
Contudo, se eu usar C89 e não pedir os diagnósticos, a compilação não produz diagnóstico nenhum. Provavelmente foi exatamente o que aconteceu com você, quando você tentou compilar.
$ gcc -std=c90 x.c
$