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 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 Elaboration Order Handling in GNAT.
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).