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).