The most desirable option from the point of view of long-term maintenance is to rearrange the program so that the elaboration problems are avoided. One useful technique is to place the elaboration code into separate child packages. Another is to move some of the initialization code to explicitly invoked subprograms, where the program controls the order of initialization explicitly. Although this is the most desirable option, it may be impractical and involve too much modification, especially in the case of complex legacy code.
When faced with an elaboration circularity, the programmer should also consider the tactics given in the suggestions section of the circularity diagnostic. Depending on the units involved in the circularity, their `with' clauses, purity, preelaborability, presence of elaboration-control pragmas and invocations at elaboration time, the binder may suggest one or more of the following tactics to eliminate the circularity:
remove pragma Elaborate for unit "..." in unit "..."
This tactic is suggested when the binder has determined that pragma
Elaborate
:
The programmer should remove the pragma as advised, and rebuild the program.
remove pragma Elaborate_All for unit "..." in unit "..."
This tactic is suggested when the binder has determined that pragma
Elaborate_All
:
The programmer should remove the pragma as advised, and rebuild the program.
change pragma Elaborate_All for unit "..." to Elaborate in unit "..."
This tactic is always suggested with the pragma Elaborate_All
elimination
tactic. It offers a different alernative of guaranteeing that the argument of
the pragma will still be elaborated prior to the unit containing the pragma.
The programmer should update the pragma as advised, and rebuild the program.
remove pragma Elaborate_Body in unit "..."
This tactic is suggested when the binder has determined that pragma
Elaborate_Body
:
Note that the binder cannot determine whether the pragma is required for other purposes, such as guaranteeing the initialization of a variable declared in the spec by elaboration code in the body.
The programmer should remove the pragma as advised, and rebuild the program.
use pragma Restrictions (No_Entry_Calls_In_Elaboration_Code)
This tactic is suggested when the binder has determined that a task activation at elaboration time:
Note that the binder cannot determine with certainty whether the task will block at elaboration time.
The programmer should create a configuration file, place the pragma within, update the general compilation arguments, and rebuild the program.
use the dynamic elaboration model (compiler switch -gnatE)
This tactic is suggested when the binder has determined that an invocation at elaboration time:
The programmer has two options:
-gnatE
to the
compilation arguments of selected files only. This approach will yield
safer elaboration orders compared to the other option because it will
minimize the opportunities presented to the dynamic model for ignoring
invocations.
-gnatE
to the general compilation arguments.
use detailed invocation information (compiler switch -gnatd_F)
This tactic is always suggested with the use of the dynamic model tactic. It causes the circularity section of the circularity diagnostic to describe the flow of elaboration code from a unit to a unit, enumerating all such paths in the process.
The programmer should analyze this information to determine which units should be compiled with the dynamic model.
remove the dependency of unit "..." on unit "..." from the argument of switch -f
This tactic is suggested when the binder has determined that a dependency
present in the forced-elaboration-order file indicated by binder switch
-f
:
The programmer should edit the forced-elaboration-order file, remove the dependency, and rebind the program.
remove switch -f
This tactic is suggested in case editing the forced-elaboration-order file is not an option.
The programmer should remove binder switch -f
from the binder
arguments, and rebind.
diagnose all circularities (binder switch -d_C)
By default, the binder will diagnose only the highest-precedence circularity.
If the program contains multiple circularities, the binder will suggest the
use of binder switch -d_C
in order to obtain the diagnostics of all
circularities.
The programmer should add binder switch -d_C
to the binder
arguments, and rebind.
If none of the tactics suggested by the binder eliminate the elaboration circularity, the programmer should consider using one of the legacy elaboration models, in the following order:
-H
.
-gnatH
and binder switch -H
.
-gnatH
-gnatJ
and binder switch -H
.
-gnatH
-gnatJ
-gnatE
and binder switch
-H
.