Tengo una biblioteca que creé,
mylib.c:
#include <mylib.h>
int
testlib() {
printf("Hello world\n");
return (0);
}
mylib.h:
#include <stdio.h>
extern int testlib();
En mi programa, intenté llamar a esta función de biblioteca:
myprogram.c:
#include <mylib.h>
int
main (int argc, char *argv[]) {
testlib();
return (0);
}
Cuando intento compilar este programa me sale el siguiente error:
En el archivo incluido desde myprogram.c: 1 mylib.h: 2 advertencia: la declaración de función no es un prototipo
Estoy usando: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
Mi pregunta es, ¿cuál es la forma correcta de declarar un prototipo de función?
Respuestas:
En C
int foo()
yint foo(void)
son diferentes funciones.int foo()
acepta un número arbitrario de argumentos, mientras queint foo(void)
acepta 0 argumentos. En C ++ significan lo mismo. Le sugiero que usevoid
consistentemente cuando no quiere decir argumentos.Si tiene una variable
a
,extern int a;
es una forma de decirle al compilador quea
es un símbolo que podría estar presente en una unidad de traducción diferente (el compilador C habla por el archivo fuente), no lo resuelva hasta el momento del enlace. Por otro lado, los símbolos que son nombres de funciones se resuelven de todos modos en el momento del enlace. El significado de un especificador de clase de almacenamiento en una función (extern
,static
) solo afecta su visibilidad yextern
es el valor predeterminado, porextern
lo que en realidad es innecesario.Sugiero eliminar el
extern
, es extraño y generalmente se omite.fuente
(void)
en C para indicar que una función no toma argumentos. En C ++, a menos que necesite específicamente su código para compilar tanto como C como C ++, simplemente use()
.Respuesta rápida: cambie
int testlib()
aint testlib(void)
para especificar que la función no acepta argumentos.Un prototipo es, por definición, una declaración de función que especifica el tipo (s) de los argumentos de la función.
Una declaración de función no prototipo como
es una declaración de estilo antiguo que no especifica el número o los tipos de argumentos. (Antes del estándar ANSI C de 1989, este era el único tipo de declaración de función disponible en el lenguaje). Puede llamar a tal función con cualquier número arbitrario de argumentos, y el compilador no está obligado a quejarse, pero si el la llamada es inconsistente con la definición , su programa tiene un comportamiento indefinido.
Para una función que toma uno o más argumentos, puede especificar el tipo de cada argumento en la declaración:
Las funciones sin argumentos son un caso especial. Lógicamente, los paréntesis vacíos habrían sido una buena forma de especificar que un argumento pero esa sintaxis ya estaba en uso para las declaraciones de funciones de estilo antiguo, por lo que el comité ANSI C inventó una nueva sintaxis usando la
void
palabra clave:Una definición de función (que incluye código para lo que realmente hace la función) también proporciona una declaración . En su caso, tiene algo similar a:
Esto proporciona una declaración de no prototipo para
testlib
. Como definición, esto le dice al compilador quetestlib
no tiene parámetros, pero como una declaración, solo le dice al compilador quetestlib
toma algunos números y tipos de argumentos no especificados pero fijos.Si cambia
()
a(void)
la declaración se convierte en un prototipo.La ventaja de un prototipo es que si llama accidentalmente
testlib
con uno o más argumentos, el compilador diagnosticará el error.(C ++ tiene reglas ligeramente diferentes. C ++ no tiene declaraciones de funciones de estilo antiguo, y los paréntesis vacíos significan específicamente que una función no tiene argumentos. C ++ admite la
(void)
sintaxis para mantener la coherencia con C. Pero a menos que necesite específicamente su código para compilar ambos como C y como C ++, probablemente debería usar()
en C ++ y la(void)
sintaxis en C.)fuente
Tratar:
fuente