todas - Debe declarar prototipo de función en C?
tipos de funciones en c (10)
C permite llamar a funciones aunque no hayan sido declaradas previamente, pero le recomiendo que declare un prototipo para todas las funciones antes de usarlas para que el compilador pueda guardarlo si utiliza los argumentos incorrectos.
Esta pregunta ya tiene una respuesta aquí:
Soy un poco nuevo en C (tengo experiencia anterior en Java, C # y algo de C ++). En C, ¿es necesario declarar un prototipo de función o puede el código compilar sin él? ¿Es una buena práctica de programación hacerlo? ¿O solo depende del compilador? (Estoy ejecutando Ubuntu 9.10 y usando el Compilador GNU C, o gcc, bajo el código :: IDE de bloques)
Debe poner declaraciones de funciones en el archivo de encabezado (Xh) y la definición en el archivo de origen (Xc). Luego, otros archivos pueden #include "Xh"
y llamar a la función.
El prototipo de función no es obligatorio según el estándar C99
.
En ANSI C (es decir C89 o C90), no tiene que declarar un prototipo de función; sin embargo, es una mejor práctica usarlos. La única razón por la que el estándar le permite no usarlos es por compatibilidad con códigos muy antiguos.
Si no tiene un prototipo y llama a una función, el compilador deducirá un prototipo de los parámetros que pasa a la función. Si declara la función más tarde en la misma unidad de compilación, obtendrá un error de compilación si la firma de la función es diferente de lo que el compilador adivinó.
Peor aún, si la función está en otra unidad de compilación, no hay forma de obtener un error de compilación, ya que sin un prototipo no hay forma de verificarlo. En ese caso, si el compilador se equivoca, podría obtener un comportamiento indefinido si la llamada de función empuja diferentes tipos en la pila de lo que espera la función.
La convención es declarar siempre un prototipo en un archivo de encabezado que tiene el mismo nombre que el archivo fuente que contiene la función.
En C99 o C11, el estándar C requiere una declaración de función en el alcance antes de llamar a cualquier función. Muchos compiladores no aplican esta restricción en la práctica a menos que los obligue a hacerlo.
En C, si no declaramos un prototipo de función y usamos la definición de función, no hay problema y el programa compila y genera el resultado si el tipo de retorno de la función es "entero". En todas las demás condiciones, aparece el error del compilador. La razón es que si llamamos a una función y no declaramos un prototipo de función, el compilador genera un prototipo que devuelve un número entero y busca la definición de función similar. si el prototipo de función coincide entonces compila con éxito. Si el tipo de retorno no es entero, los prototipos de función no coinciden y genera un error. Por lo tanto, es mejor declarar el prototipo de función en los archivos de encabezado.
No es absolutamente necesario declarar una función para compilar el código de llamada. Sin embargo, hay advertencias. Se supone que la función no declarada devuelve int
y el compilador emitirá advertencias primero sobre la función no declarada y luego sobre cualquier desajuste en el tipo de devolución y tipos de parámetros.
Habiendo dicho eso, es obvio que declarar funciones correctamente con prototipos es una práctica mucho mejor.
No es obligatorio, pero es una mala práctica no usar prototipos.
Con los prototipos, el compilador puede verificar que está llamando a la función correctamente (usando el número y tipo correcto de parámetros).
Sin prototipos, es posible tener esto:
// file1.c
void doit(double d)
{
....
}
int sum(int a, int b, int c)
{
return a + b + c;
}
y esto:
// file2.c
// In C, this is just a declaration and not a prototype
void doit();
int sum();
int main(int argc, char *argv[])
{
char idea[] = "use prototypes!";
// without the prototype, the compiler will pass a char *
// to a function that expects a double
doit(idea);
// and here without a prototype the compiler allows you to
// call a function that is expecting three argument with just
// one argument (in the calling function, args b and c will be
// random junk)
return sum(argc);
}
Nunca se requiere declarar un prototipo para una función en C, ni en C "antiguo" (incluido C89 / 90) ni en C nuevo (C99). Sin embargo, hay una diferencia significativa entre C89 / 90 y C99 con respecto a las declaraciones de funciones.
En C89 / 90 no fue necesario declarar una función en absoluto. Si la función no se declara en el punto de la llamada, el compilador "adivina" (infiere) la declaración implícitamente a partir de los tipos de argumentos pasados en la llamada y asume que el tipo de retorno es int
.
Por ejemplo
int main() {
int i = foo(5);
/* No declaration for `foo`, no prototype for `foo`.
Will work in C89/90. Assumes `int foo(int)` */
return 0;
}
int foo(int i) {
return i;
}
En C99, todas las funciones que llame deben declararse antes del punto de la llamada. Sin embargo, aún no es necesario declararlo específicamente con un prototipo . Una declaración no prototipo también funcionará. Esto significa que en C99 la regla "implícita int
" ya no funciona (para los tipos de retorno de función inferida, en este caso), pero los tipos de parámetros aún se pueden adivinar a partir de los tipos de argumento si la función se declara sin un prototipo.
El ejemplo anterior no se compilará en C99, ya que foo
no está declarado en el punto de la llamada. Sin embargo, puede agregar una declaración no prototipo
int foo(); /* Declares `foo`, but still no prototype */
int main() {
int i = foo(5);
/* No prototype for `foo`, although return type is known.
Will work in C99. Assumes `int foo(int)` */
return 0;
}
...
y terminan con un código C99 válido.
Sin embargo, siempre es una buena práctica declarar un prototipo para la función antes de llamarlo.
Una nota adicional: dije anteriormente que nunca se requiere declarar un prototipo de función. De hecho, para algunas funciones es un requisito. Para llamar correctamente una función variadic en C ( printf
por ejemplo), la función debe declararse con un prototipo antes del punto de la llamada. De lo contrario, el comportamiento no está definido. Esto se aplica tanto a C89 / 90 como a C99.
Seleccione el menú ''Opciones'' y luego seleccione ''Compiler | Opciones de C ++ ''. En el cuadro de diálogo que aparece, seleccione ''CPP siempre'' en las opciones ''Usar compilador de C ++''. Nuevamente seleccione el menú ''Opciones'' y luego seleccione ''Entorno | Editor''. Asegúrese de que la extensión predeterminada sea ''C'' en lugar de ''CPP''.
no es obligatorio, si la función está definida antes de su uso.