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_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:
Elaboratepragmas, and then inhibit the generation of implicit
Elaborate_Allpragmas 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).