Declaración de funciones

La declaración de una función describe un prototipo sin especificar el cuerpo de la función. En lugar de un bloque con cuerpo, se pone punto y coma.

La declaración es necesaria para que el compilador pueda comprobar en fragmentos de código posteriores cómo se llama correctamente a la función por su nombre, pasándole argumentos y obteniendo el resultado.

Toda la definición de la función (incluido el cuerpo) es también una declaración, por lo que no es necesario declarar una función además de la definición.

Por ejemplo, la declaración de la función Fibo anterior podría tener este aspecto:

int Fibo(const int n);

Se utilizan declaraciones y definiciones de funciones independientes cuando se construye un programa a partir de varios archivos con texto fuente: entonces, la declaración se realiza en el archivo de encabezado con la extensión mqh (véase la sección sobre la directiva #include del preprocesador), que está incluida en los archivos en los que se utiliza la función, y la definición de la función se implementa sólo en uno de los archivos. La coincidencia de la firma de la función en la declaración y la definición proporciona protección contra errores. En otras palabras: una única declaración garantiza la coherencia de los cambios realizados en todo el código fuente

Si declaramos una función y la llamamos en algún lugar del código, pero no proporcionamos una definición totalmente apropiada para la misma, el compilador arrojará el error «La función 'Nombre' debe tener un cuerpo». Esto suele ocurrir cuando hay erratas o imprecisiones en la declaración o en la definición, así como en el proceso de cambio de los códigos fuente, cuando parte de las correcciones ya se han hecho y la otra parte probablemente se ha olvidado.

Si la función se declara y no se utiliza en ninguna parte, el compilador tampoco requiere su definición; dicho elemento simplemente se «recorta» del programa binario.

En la sección Sentencias de declaración y definición vimos un ejemplo de la función Init (script StmtDeclaration.mq5), que se utilizó para inicializar variables. Allí, en concreto, se demostró el problema de que la variable global k no puede definirse antes de la función Init, ya que el valor inicial k se obtiene llamando a Init. El compilador arroja el error «'Init' es un identificador desconocido».

Ahora sabemos que ese problema puede resolverse con una declaración. En el script FuncDeclaration.mq5 hemos añadido la siguiente declaración de la función Init antes de la variable k, y dejado la definición Init después de k.

// preliminary declaration
int Init(const int v);
// before adding preliminary declaration above
// here was an error: 'Init' is an unknown identifier
int k = Init(-1);
int Init(const int v)
{
   Print("Init: "v);
   return v;
}

Ahora el script se compila normalmente. Técnicamente, en este caso podríamos simplemente mover la función por encima de la variable sin una declaración preliminar. Lo hicimos para explicar el concepto. Sin embargo, hay casos de dependencia mutua de los elementos del lenguaje entre sí (por ejemplo, las clases), cuando es imposible prescindir de una declaración previa dentro del mismo archivo.