Programación en Ada/Compilación separada y dependiente
Ada realiza una compilación separada y dependiente.
Una compilación separada significa que el programa principal y un subprograma pueden escribirse por separado en ficheros distintos.
Una compilación dependiente significa que el compilador va a llevar a cabo la comprobación de que los tipos y el número de parámetros de la invocación en el subprograma invocante concuerdan con los tipos y el número de parámetros del subprograma invocado.
En otros lenguajes en los que se realiza una compilación independiente (por ejemplo el lenguaje C), no se advierte que los parámetros de llamada se corresponden y compila correctamente. Esta situación en un sistema de control es intolerable. El fallo no se detecta en la compilación y puede que tampoco en las pruebas.
En Ada, cuando desde una unidad de biblioteca se utiliza un tipo o un subprograma de otra unidad, se puede entender que depende semánticamente de ella.
Cuando una unidad ha sido compilada con éxito, se incorpora a la biblioteca del lenguaje. Así, cuando el compilador encuentra una llamada a un subprograma, contrasta el número y el tipo de los parámetros de la llamada contra la declaración del subprograma invocado, declaración que debe haber sido previamente compilada y que, en consecuencia, debe estar ya en la biblioteca. Por lo tanto, se puede decir que es la biblioteca Ada la que implementa la dependencia.
Ada permite incluso escribir y compilar la subrutina invocante antes que la subrutina invocada de forma consistente. Esto se consigue compilando únicamente la especificación, dejando la compilación del cuerpo para más tarde. En dicha especificación se deja detallado el nombre, el número y los tipos de los parámetros, además de indicar si son de entrada, salida o ambos. Esta es toda la información que necesita el compilador para compilar una llamada a un subprograma. Cuando, posteriormente, se compile el cuerpo del subprograma, se comprobará que es consistente con la especificación.
La forma de expresar que una unidad depende de otra se realiza mediante la cláusula with. Cuando el compilador encuentra dicha cláusula, extrae de la biblioteca el interfaz de la unidad que acompaña a with.
El orden de compilación es el siguiente: una unidad sólo se incorpora a la biblioteca después de que todas las unidades de las que depende se han incorporado también a la biblioteca. Ello implica que:
- Si especificación y cuerpo de una unidad se compilan por separado, es preciso compilar antes la especificación.
- Si la especificación de una unidad es cambiada y, por lo tanto, es recompilada de nuevo, todas las unidades que dependen de ella deben ser recompiladas.
- Si el cuerpo de una unidad se cambia de una forma consistente con su especificación, las unidades que dependen de esta unidad no necesitan ser recompiladas.
El lenguaje Ada viene con varios paquetes predefinidos como Text_IO. Estos paquetes ya han sido incorporados a la biblioteca del lenguaje. Hay, sin embargo, una excepción que es el paquete Standard, que no necesita la cláusula with. Finalmente, todas las unidades incorporadas a la biblioteca Ada deben tener nombres diferentes. En otro caso, se produce el reemplazamiento de la unidad residente por la nueva unidad con el mismo nombre.
Notese que cuando se dice que una unidad se ha de compilar antes que otra no quiere decir que el programador se tenga que preocupar de estos temas, pues los entornos de desarrollo de Ada vienen acompañados de herramientas de compilación que se encargan de recompilar todas las unidades necesarias y sólo las que han quedado obsoletas por un cambio en el código fuente. Por ejemplo, con el compilador GNAT, esta herramienta es gnatmake.