2008-09-03 15 views
129

tengo una biblioteca creé,declaración de la función no es un prototipo

mylib.c:

#include <mylib.h> 
int 
testlib() { 
    printf("Hello world\n"); 
    return (0); 
} 

mylib.h:

#include <stdio.h> 
extern int testlib(); 

En mi programa , He intentado 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:

In file included from myprogram.c:1 
mylib.h:2 warning: function declaration isn't a prototype

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?

+1

Eliminar extern de la declaración en mylib.h Especialmente si está escribiendo un programa C puro, el externo la declaración es innecesaria allí. –

Respuesta

274

En C y int foo()int foo(void) son diferentes funciones. int foo() acepta un número arbitrario de argumentos, mientras que int foo(void) acepta 0 argumentos. En C++ significan lo mismo. Le sugiero que use void consistentemente cuando quiere decir que no hay argumentos.

Si tiene una variable a, extern int a; es una forma de decirle al compilador que a es un símbolo que pudiera estar presente en una unidad de traducción diferente (compilador C hable por archivo de origen), no resuelven hasta el momento del enlace . Por otro lado, los símbolos que son nombres de funciones se resuelven de todos modos en el tiempo del enlace. El significado de un especificador de clase de almacenamiento en una función (extern, static) solo afecta su visibilidad y extern es el valor predeterminado, por lo que extern es realmente innecesario.

Sugiero eliminar el extern, es extraño y por lo general se omite.

+5

Use '(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 '()'. –

17

Probar:

extern int testlib(void); 
+27

-1: Sin explicación alguna. –

+17

+1: responde exactamente la pregunta. – harper

37

Respuesta rápida: cambie int testlib() a int testlib(void) para especificar que la función no requiere argumentos.

Un prototipo es, por definición, una declaración de función que especifica el (los) tipo (s) de argumento (s) de la función.

Una declaración de la función prototipo no como

int foo(); 

es una declaración de estilo antiguo que no especifica el número o el tipo 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 dicha función con cualquier número arbitrario de argumentos, y no es necesario que el compilador se queje, 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, se puede especificar el tipo de cada argumento en la declaración:

int bar(int x, double y); 

Funciones sin argumentos son un caso especial. Lógicamente, los paréntesis vacíos habría sido una buena manera de especificar que un argumento, sino que la sintaxis ya estaba en uso de declaraciones de funciones de estilo antiguo, por lo que el comité ANSI C inventado una nueva sintaxis utilizando el void palabra clave:

int foo(void); /* foo takes no arguments */ 

Una función definición (que incluye código para lo que realmente hace la función) también proporciona una declaración . En su caso, usted tiene algo similar a:

int testlib() 
{ 
    /* code that implements testlib */ 
} 

Esto proporciona una declaración no prototipo para testlib. Como definición, esto le dice al compilador que testlib no tiene parámetros, pero como una declaración, solo le dice al compilador que testlib toma un número no especificado pero fijo y tipo (s) de argumentos.

Si cambia () a (void) la declaración se convierte en un prototipo.

La ventaja de un prototipo es que si accidentalmente llama al testlib con uno o más argumentos, el compilador diagnosticará el error.

(C++ tiene reglas ligeramente diferentes. C++ no tiene declaraciones de funciones antiguas, y los paréntesis vacíos significan específicamente que una función no toma argumentos. C++ admite la sintaxis (void) para 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 el () en C++ y la sintaxis (void) en C.)

Cuestiones relacionadas