Elaboration order (GNAT Reference Manual)

#### 20.4.4 Elaboration order ¶

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:

- Modify the program to eliminate the circularities, e.g., by moving elaboration-time code into explicitly-invoked procedures
- Constrain the elaboration order by including explicit `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).