¿Por qué necesitamos un prototipo en función?

C como lenguaje fue diseñado hace mucho tiempo, cuando los compiladores estaban muy restringidos en el tiempo de cálculo. Muchas de sus opciones de diseño existen para hacer que los compiladores sean más fáciles de escribir, dadas las limitaciones informáticas de la época.

Los prototipos son uno de esos ejemplos. La razón principal por la que existen es para que el compilador pueda pasar por el programa exactamente una vez, sabiendo qué funciones están dentro del alcance en un momento dado. Para hacer esto, las funciones tendrían que declararse antes de ser utilizadas; Los prototipos le permiten declarar una función sin implementar su cuerpo hasta más tarde. Si no hubiera forma de hacerlo, sería realmente complicado escribir código donde, por ejemplo, dos funciones se referencian entre sí.

Esto es adicionalmente complicado, y más importante, por el modelo C elegido para su preprocesador. En esencia, no existe un sistema de módulos real; en cambio, todos los archivos que usa se concatenan en un gran programa en C que se pasa al compilador. Para que esto funcione correctamente y para permitir la compilación por separado, entre otras cosas, C necesita un sistema de archivos de encabezado que especifique cómo llamar a algún código, pero no el código en sí. ¡Esto es exactamente lo que hacen los prototipos de funciones!

Entonces, la historia final es que es una peculiaridad histórica. La mayoría de los lenguajes modernos que no se basan directamente en C han omitido tanto los prototipos de funciones como los archivos de encabezado, por lo que ciertamente no es algo que realmente necesite.

En ANSI C, no tiene que declarar un prototipo de función; sin embargo, es una buena práctica usarlos.
Primero veamos a qué propósito sirve el tipo de función.

1) Le dice al tipo de retorno de los datos que la función devolverá.
2) Indica el número de argumentos pasados ​​a la función.
3) Indica los tipos de datos de cada uno de los argumentos pasados.
4) También indica el orden en que se pasan los argumentos a la función.

El prototipo de una función también se denomina firma de la función.
¿Qué pasa si uno no especifica el prototipo de la función?
La producción de los siguientes tipos de programas generalmente se solicita en muchos lugares.

  int main ()
 {
    foo ();
    getchar ();
    devuelve 0;
 }
 vacío foo ()
 {
    printf ("llamado foo");
 }

Si no se especifica el prototipo de la función, el comportamiento es específico del estándar C (C90 o C99) que implementan los compiladores. Hasta el estándar C90, los compiladores de C asumieron el tipo de retorno del prototipo de función omitido como int. Y esta suposición en el lado del compilador puede conducir a un comportamiento del programa no especificado.

El estándar C99 posterior especificó que los compiladores ya no pueden asumir el tipo de retorno como int. Por lo tanto, C99 se volvió más restringido en la verificación de tipo de prototipo de función. Pero para hacer que el estándar C99 sea compatible con versiones anteriores, en la práctica, los compiladores lanzan la advertencia que dice que el tipo de retorno se asume como int. Pero siguen adelante con la compilación. Por lo tanto, es responsabilidad de los programadores asegurarse de que el prototipo de la función asumida y el tipo de función real coincidan.

Para evitar todos estos detalles de implementación de los estándares C, es mejor tener un prototipo de función.

En versiones anteriores de C, si una función no se declaraba previamente y su nombre aparecía en una expresión seguida de un paréntesis izquierdo, se declara implícitamente como una función que devuelve un int y no se supone nada sobre sus argumentos.

Considere el siguiente código:

  #include 

 int foo (int n);  // prototipo de función

 int main (nulo)
 {
	 int bar = foo (2);
	 printf ("% d", barra);
 }

 int foo (int n) // definición de función
 {
	 retorno ++ n;  // alguna operación
 }

Si se omite el prototipo de foo () , la función se ejecutará sin ningún argumento y terminará operando en algún dato aleatorio en la pila.

Al incluir el prototipo de la función, le informa al compilador que la función foo () toma un argumento entero y le permite al compilador detectar este tipo de errores y hacer que el proceso de compilación se ejecute sin problemas.

En el estándar C99, la omisión de un prototipo de función dará como resultado un error de compilación.

Necesitamos dar la firma de la función, para decirle al compilador cómo se vería la función. La función puede residir en otro módulo, pero el compilador aún necesita saber cómo se ve, para saber cuántos parámetros debe pasar, etc.

Sin prototipo, ¿cómo llamarás a la función?

C – Funciones y prototipos