Eu tenho uma biblioteca que eu criei,
mylib.c:
#include <mylib.h>
int
testlib() {
printf("Hello world\n");
return (0);
}
mylib.h:
#include <stdio.h>
extern int testlib();
No meu programa, tentei chamar esta função de biblioteca:
myprogram.c:
#include <mylib.h>
int
main (int argc, char *argv[]) {
testlib();
return (0);
}
Quando tento compilar este programa, recebo o seguinte erro:
No arquivo incluído em myprogram.c: 1 mylib.h: 2 aviso: declaração de função não é um protótipo
Estou a usar: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
Minha pergunta é: qual é a maneira correta de declarar um protótipo de função?
Respostas:
Em C
int foo()
eint foo(void)
são diferentes funções.int foo()
aceita um número arbitrário de argumentos, enquantoint foo(void)
aceita 0 argumentos. Em C ++, eles significam a mesma coisa. Eu sugiro que você usevoid
consistentemente quando não quer dizer argumentos.Se você tiver uma variável
a
,extern int a;
é uma maneira de dizer ao compilador quea
é um símbolo que pode estar presente em uma unidade de tradução diferente (o compilador C fala pelo arquivo de origem), não o resolva até o tempo do link. Por outro lado, os símbolos que são nomes de funções são resolvidos de qualquer maneira no momento do link. O significado de um especificador de classe de armazenamento em uma função (extern
,static
) afeta apenas sua visibilidade eextern
é o padrão, portanto,extern
é realmente desnecessário.Sugiro remover o
extern
, é estranho e geralmente é omitido.fonte
(void)
em C para indicar que uma função não aceita argumentos. No C ++, a menos que você precise especificamente do seu código para compilar como C e C ++, basta usar()
.Resposta rápida: altere
int testlib()
paraint testlib(void)
para especificar que a função não aceita argumentos.Um protótipo é, por definição, uma declaração de função que especifica o (s) tipo (s) do (s) argumento (s) da função.
Uma declaração de função não protótipo como
é uma declaração de estilo antigo que não especifica o número ou os tipos de argumentos. (Antes do padrão ANSI C de 1989, esse era o único tipo de declaração de função disponível no idioma.) Você pode chamar essa função com qualquer número arbitrário de argumentos, e o compilador não precisa se queixar - mas se o Se a chamada for inconsistente com a definição , seu programa tem um comportamento indefinido.
Para uma função que recebe um ou mais argumentos, você pode especificar o tipo de cada argumento na declaração:
Funções sem argumentos são um caso especial. Logicamente, parênteses vazios teriam sido uma boa maneira de especificar esse argumento, mas essa sintaxe já estava sendo usada para declarações de função de estilo antigo; portanto, o comitê ANSI C inventou uma nova sintaxe usando a
void
palavra-chave:Uma definição de função (que inclui código para o que a função realmente faz) também fornece uma declaração . No seu caso, você tem algo semelhante a:
Isso fornece uma declaração sem protótipo para
testlib
. Como definição, isso informa ao compilador quetestlib
não possui parâmetros, mas como declaração, ele diz apenas ao compilador quetestlib
utiliza algum número e tipo (s) de argumentos não especificados, mas fixos.Se você mudar
()
para(void)
a declaração, torna-se um protótipo.A vantagem de um protótipo é que, se você chamar acidentalmente
testlib
com um ou mais argumentos, o compilador diagnosticará o erro.(O C ++ possui regras ligeiramente diferentes. O C ++ não possui declarações de função no estilo antigo, e parênteses vazios significam especificamente que uma função não aceita argumentos. O C ++ suporta a
(void)
sintaxe da consistência com C. Mas, a menos que você precise especificamente do seu código para compilar os dois, C e como C ++, você provavelmente deve usar o()
em C ++ e a(void)
sintaxe em C.)fonte
Experimentar:
fonte