paulo1205
(usa Ubuntu)
Enviado em 12/08/2013 - 01:43h
O correto é declarar sempre, a fim de que o compilador consiga detectar uso indevido e possa sinalizar o programador, para que corrija o código.
Considere o seguinte exemplo.
#include <stdio.h>
int main(void){
int a=f(5);
printf("%d\n", a);
return 0;
}
int f(int x, int y){
return x+y;
}
Esse código vai compilar, mas ele claramente tem um problema: a função
f() espera dois parâmetros, mas é invocada com apenas um ao longo do programa.
E o pior é que isso compila sem indicar erro e produz um executável que vai dar problema com certeza. Mas por quê é assim?
Porque até 1989 não existia um padrão para a linguagem C e, por várias razões históricas (que eu não vou discutir aqui, mas que são fartamente apresentadas na Internet, inclusive no site do falecido Dennis Ritchie, o pai da linguagem C, em
http://cm.bell-labs.com/cm/cs/who/dmr/index.html), os compiladores antigos prescindiam de declaração de funções. Quando uma função não declarada
func() era encontrada num programa, o compilador simplesmente assumia que ela podia ser usada como se tivesse sido declarada do seguinte modo.
int func();
Tal declaração implícita assumida significa: "
func é uma função que recebe um número qualquer de argumentos de quaisquer tipos, e devolve um resultado do tipo
int".
Esse "conforto" fazia com que muita gente simplesmente não declarasse função alguma, a não ser quando o tipo do argumento retornado não fosse
int. No programa acima, se eu quisesse que a implementação de
func() a fizesse devolver um valor do tipo
double, eu seria obrigado a declará-la; se eu não fizesse isso, seu uso no corpo de
main() dispararia a assunção implícita de uma declaração devolvendo
int, e ao encontrar, depois, a declaração devolvendo
double, o compilador daria uma mensagem de erro dizendo que a implementação da função estava com o tipo incorreto.
(Se bem que eu não colocaria a mão no fogo a esse respeito. Não duvido que alguns compiladores ainda mais lenientes não indicassem erro nem nesse caso.)
Quando o primeiro padrão do C surgiu em 1989, o comitê de padronização entendeu que a declaração de protótipos de funções ajudava a evitar vários tipos de acidentes e até mesmo de mau uso intencional, e recomendou fortemente o uso de protótipos, e fez com que todas as funções da biblioteca padrão fossem documentadas com os protótipos corretos. No entanto, como já havia, então, uma quantidade muito grande de código em C escrito nos moldes pré-padronização, o comitê decidiu que tal código deveria continuar compilando sem nem mesmo exibir qualquer mensagem de aviso sobre a falta de declaração,
a não ser que o usuário explicitamente pedisse para ser avisado (no meu entendimento, deveria ser o contrário: os usuários deveriam ser avisados sobre o comportamento obsoleto por padrão; tenho certeza de que só isso teria ajudado muitos programadores a perder menos tempo "batendo cabeça" na caça de bugs em seus programas).
Versões posteriores do padrão do C (1999 e 2011) transformaram esse comportamento. Agora, por padrão se avisa, e se o usuário quiser suprimir os avisos ou ignorá-los, será sua responsabilidade.
Por uma questão de segurança, a fim de evitar acidentes, eu recomendo a todos que sempre liguem as opções de diagnóstico dos seus compiladores. Mais do que isso, recomendo até que entre essas opções se coloquem aquelas que transformam avisos de advertência em erros, para que o compilador realmente
rejeite código suspeito, em lugar de somente alertar a respeito. No caso do GCC eu sempre recomendo as seguintes opções de compilação.
-O2 -Wall -Werror -pedantic
Usando tais opções, o código acima não compilaria, mas daria as seguintes mensagens de erro.
lixo.c: In function 'main':
lixo.c:4:2: error: implicit declaration of function 'f' [-Werror=implicit-function-declaration]
cc1: all warnings being treated as errors