The sequence by which the elaboration code of all units within a partition is executed is referred to as `elaboration order'.
Within a single unit, elaboration code is executed in sequential order.
package body Client is Result : ... := Server.Func; procedure Proc is package Inst is new Server.Gen; begin Inst.Eval (Result); end Proc; begin Proc; end Client;
In the example above, the elaboration order within package body Client
is
as follows:
Result
is elaborated.
Server.Func
is invoked.
Proc
is elaborated.
Proc
is invoked.
Server.Gen
is instantiated as Inst
.
Inst
is elaborated.
Inst.Eval
is invoked.
The elaboration order of all units within a partition depends on the following factors:
A program may have several elaboration orders depending on its structure.
package Server is function Func (Index : Integer) return Integer; end Server;package body Server is Results : array (1 .. 5) of Integer := (1, 2, 3, 4, 5); function Func (Index : Integer) return Integer is begin return Results (Index); end Func; end Server;with Server; package Client is Val : constant Integer := Server.Func (3); end Client;with Client; procedure Main is begin null; end Main;
The following elaboration order exhibits a fundamental problem referred to as `access-before-elaboration' or simply `ABE'.
spec of Server spec of Client body of Server body of Main
The elaboration of Server
’s spec materializes function Func
, making it
callable. The elaboration of Client
’s spec elaborates the declaration of
Val
. This invokes function Server.Func
, however the body of
Server.Func
has not been elaborated yet because Server
’s body comes
after Client
’s spec in the elaboration order. As a result, the value of
constant Val
is now undefined.
Without any guarantees from the language, an undetected ABE problem may hinder
proper initialization of data, which in turn may lead to undefined behavior at
run time. To prevent such ABE problems, Ada employs dynamic checks in the same
vein as index or null exclusion checks. A failed ABE check raises exception
Program_Error
.
The following elaboration order avoids the ABE problem and the program can be successfully elaborated.
spec of Server body of Server spec of Client body of Main
Ada states that a total elaboration order must exist, but it does not define what this order is. A compiler is thus tasked with choosing a suitable elaboration order which satisfies the dependencies imposed by `with' clauses, unit categorization, elaboration-control pragmas, and invocations performed in elaboration code. Ideally an order that avoids ABE problems should be chosen, however a compiler may not always find such an order due to complications with respect to control and data flow.