2011-05-08 13 views
24

¿Puede alguien explicarme por qué se compila el siguiente código sin advertencia ni error?Función C sin comportamiento de parámetros

Espero que el compilador me advierta que la prueba de función no espera ningún argumento. Pero el código compila y ejecuta la prueba de función recursivamente.

#include <stdio.h> 
#include <stdlib.h> 

static void test1(int a, int b, int c) {} 

static void test() { 
    printf("HERE\n"); 
    test(1,2,3); 
} 

void main() { 
    test(); 
} 
+4

@Chris Sí. ¿Por qué? ¿Por qué cuando las personas publican aquí hacen que su código de ejemplo sea tan difícil de leer? ¿Qué hay de malo con el uso de nombres completamente diferentes para las cosas en lugar de los que son casi lo mismo? Por favor, personas, no utilicen nombres como "prueba" y "prueba1", usen nombres como "A", "B" y "C". –

+0

Como un aparte de las respuestas que indican que un conjunto de parámetros vacío no es un prototipo en C, puede habilitar advertencias para prototipos perdidos en GCC con '-Wstrict-prototypes' y en MSVC con'/Wall/W4' . Tenga en cuenta que '-Wall' no habilita esa advertencia en GCC (no estoy seguro de por qué). –

+0

Vaya, aprobé una edición de esta pregunta cuando quise rechazarla. –

Respuesta

45

En C++, void test() declara una función que no toma parámetros (y no devuelve nada).

En C, void test() declara una función que toma un número de parámetros no especificado (pero no variable) (y no devuelve nada). Entonces todas sus llamadas son válidas (según el prototipo) en C.

En C, use void test(void) para declarar una función que realmente no tome parámetros (y no devuelva nada).

+0

¿qué quiere decir con no especificado (pero no variable), puedo referir esos parámetros dentro de la función? –

+0

@John - Si la función está _definida_ con parámetros, sí. Tendría que hacer 'void test(); int main (void) {test(); } prueba de vacío (int a, int b, int c) {puts ("Yo"); prueba (a, b, c); } '(o poner' test' en un archivo separado.) –

+2

+1 para "no especificado (pero no variable)"; @John significa que el compilador no verificará el número (o tipo) de argumentos, pero debe llamar a la función con argumentos que coincidan con los parámetros en la definición. Tenga en cuenta que la definición y la declaración no necesitan estar en el mismo archivo. En el ejemplo proporcionado por el OP, 'test' se define sin parámetros y, aunque el prototipo no lo fuerza, al llamar' test() 'con 1 o más argumentos invoca Comportamiento no definido – pmg

11

Cuando se declara una función con una lista de argumentos vacía, se invoca K & R (pre-prototipo) semántica y nada se asume acerca de la lista de parámetros; esto es para que el código pre-ANSI C aún se compile. Si desea una función de prototipo con una lista de parámetros vacía, use (void) en lugar de ().

Cuestiones relacionadas