The implementation can choose any elaboration order consistent with the unit
dependency relationship. This freedom means that some orders can result in
Program_Error being raised due to an ’Access Before Elaboration’: an attempt
to invoke a subprogram before its body has been elaborated, or to instantiate
a generic before the generic body has been elaborated. By default GNAT
attempts to choose a safe order (one that will not encounter access before
elaboration problems) by implicitly inserting Elaborate
or
Elaborate_All
pragmas where
needed. However, this can lead to the creation of elaboration circularities
and a resulting rejection of the program by gnatbind. This issue is
thoroughly described in the `Elaboration Order Handling in GNAT' appendix
in the GNAT User’s Guide.
In brief, there are several
ways to deal with this situation:
Elaborate_Body
or
Elaborate
pragmas, and then inhibit the generation of implicit
Elaborate_All
pragmas either globally (as an effect of the `-gnatE' switch) or locally
(by selectively suppressing elaboration checks via pragma
Suppress(Elaboration_Check)
when it is safe to do so).