2012-07-25 15 views
20

Me pregunto por qué esto se compilará:¿Por qué el prototipo y la definición de una función en C pueden diferir?

int test(); 

int main() { return test((void*)0x1234); } 
int test(void* data) { return 0; } 

¿Por qué no el compilador emitir cualquier error/advertencia acerca de que (probé sonido metálico, gcc)? Si cambio el valor de retorno no compilará, pero los argumentos pueden diferir?

+1

posible duplicado de [C argumentos vacíos] (http://stackoverflow.com/questions/693788/c-void-arguments) –

Respuesta

28

Si cambia:

int test(); 

a:

int test(void); 

obtendrá el error esperado:

foo.c:4: error: conflicting types for ‘test’ 
foo.c:1: error: previous declaration of ‘test’ was here 

Esto se debe a int test(); simplemente declara una función que toma ningún parámetro (y por tanto es compatible con su posterior definición de test), mientras que int test(void); es un prototipo de la función real que declara una función que toma no parámetros (y que es no compatible con la definición posterior).

+3

+1, para indicarlo en la terminología C-ish, 'int test()' simplemente no es un prototipo, sino solo una declaración. –

+0

Pero tal comportamiento será pronto obsoleto (o al menos esto es lo que nos dice ISO C11). – AnArrayOfFunctions

15
int test(); 

en una declaración de función, ningún parámetro significa que la función toma un número de argumentos no especificado.

Esto es diferente a

int test(void); 

lo que significa que la función toma ningún argumento.

Una declaración de función sin parámetro es el antiguo estilo C de declaración de función; C marca este estilo como obsoleto y desalienta su uso. En resumen, no lo use.

En su caso, se debe utilizar una declaración de la función con la declaración de parámetros correctos:

int test(void *data); 
+0

¡Siempre me olvido que C hace eso! Incluso si fuera 'int test (void);' pero cross TU no hay ningún requisito para que se emita un diagnóstico. – Flexo

Cuestiones relacionadas