To avoid placing the entire elaboration-order burden on the programmer, Ada provides three lines of defense:
Static semantic rules restrict the possible choice of elaboration order. For instance, if unit Client ‘with’s unit Server, then the spec of Server is always elaborated prior to Client. The same principle applies to child units - the spec of a parent unit is always elaborated prior to the child unit.
Dynamic checks are performed at run time, to ensure that a target is
elaborated prior to a scenario that invokes it, thus avoiding ABE problems.
A failed run-time check raises exception
Program_Error. The following
An entry, operator, or subprogram can be called from elaboration code only when the corresponding body has been elaborated.
A generic unit can be instantiated by elaboration code only when the corresponding body has been elaborated.
A task can be activated by elaboration code only when the body of the associated task type has been elaborated.
The restrictions above can be summarized by the following rule:
‘If a target has a body, then this body must be elaborated prior to the scenario that invokes the target.’
Pragmas are provided for the programmer to specify the desired elaboration order.