text:
Buy the book!
|[ < ]
|[ > ]
|[ << ]
|[ Up ]
|[ >> ]
|[ ? ]
If the binder cannot find an acceptable order, it outputs detailed diagnostics. For example:
error: elaboration circularity detected info: "proc (body)" must be elaborated before "pack (body)" info: reason: Elaborate_All probably needed in unit "pack (body)" info: recompile "pack (body)" with -gnatwl info: for full details info: "proc (body)" info: is needed by its spec: info: "proc (spec)" info: which is withed by: info: "pack (body)" info: "pack (body)" must be elaborated before "proc (body)" info: reason: pragma Elaborate in unit "proc (body)"
In this case we have a cycle that the binder cannot break. On the one
hand, there is an explicit pragma Elaborate in
proc for
pack. This means that the body of
pack must be elaborated
before the body of
proc. On the other hand, there is elaboration
code in
pack that calls a subprogram in
proc. This means
that for maximum safety, there should really be a pragma
Elaborate_All in
pack for
proc which would require that
the body of
proc be elaborated before the body of
pack. Clearly both requirements cannot be satisfied.
Faced with a circularity of this kind, you have three different options.
Elaborate_All pragmas.
The behavior then is exactly as specified in the Ada 95 Reference Manual.
The binder will generate an executable program that may or may not
Program_Error, and then it is the programmer's job to ensure
that it does not raise an exception. Note that it is important to
compile all units with the switch, it cannot be used selectively.
Suppress (Elaboration_Checks) to suppress all such checks. For
example this pragma could be placed in the `gnat.adc' file.
Suppress (Elaboration_Check) can
be used with different granularity to suppress warnings and break
elaboration circularities:
These four cases are listed in order of decreasing safety, and therefore require increasing programmer care in their application. Consider the following program:
package Pack1 is function F1 return Integer; X1 : Integer; end Pack1; package Pack2 is function F2 return Integer; function Pure (x : integer) return integer; -- pragma Suppress (Elaboration_Check, On => Pure); -- (3) -- pragma Suppress (Elaboration_Check); -- (4) end Pack2; with Pack2; package body Pack1 is function F1 return Integer is begin return 100; end F1; Val : integer := Pack2.Pure (11); -- Elab. call (1) begin declare -- pragma Suppress(Elaboration_Check, Pack2.F2); -- (1) -- pragma Suppress(Elaboration_Check); -- (2) begin X1 := Pack2.F2 + 1; -- Elab. call (2) end; end Pack1; with Pack1; package body Pack2 is function F2 return Integer is begin return Pack1.F1; end F2; function Pure (x : integer) return integer is begin return x ** 3 - 3 * x; end; end Pack2; with Pack1, Ada.Text_IO; procedure Proc3 is begin Ada.Text_IO.Put_Line(Pack1.X1'Img); -- 101 end Proc3;
error: elaboration circularity detected info: "pack1 (body)" must be elaborated before "pack1 (body)" info: reason: Elaborate_All probably needed in unit "pack1 (body)" info: recompile "pack1 (body)" with -gnatwl for full details info: "pack1 (body)" info: must be elaborated along with its spec: info: "pack1 (spec)" info: which is withed by: info: "pack2 (body)" info: which must be elaborated along with its spec: info: "pack2 (spec)" info: which is withed by: info: "pack1 (body)"
Pack2.Pure and
Pack2.F2 in the body of
Pack1. We can see that the call to
F2 is safe, even though F2 calls F1, because the call appears after the
elaboration of the body of F1. Therefore the pragma (1) is safe, and will
remove the warning on the call. It is also possible to use pragma (2)
because there are no other potentially unsafe calls in the block.
The call to
Pure is safe because this function does not depend on the
state of
Pack2. Therefore any call to this function is safe, and it
is correct to place pragma (3) in the corresponding package spec.
Finally, we could place pragma (4) in the spec of
Pack2 to disable
warnings on all calls to functions declared therein. Note that this is not
necessarily safe, and requires more detailed examination of the subprogram
bodies involved. In particular, a call to
F2 requires that
be already elaborated.
It is hard to generalize on which of these four approaches should be
taken. Obviously if it is possible to fix the program so that the default
treatment works, this is preferable, but this may not always be practical.
It is certainly simple enough to use
but the danger in this case is that, even if the GNAT binder
finds a correct elaboration order, it may not always do so,
and certainly a binder from another Ada compiler might not. A
combination of testing and analysis (for which the warnings generated
with the
switch can be useful) must be used to ensure that the program is free
of errors. One switch that is useful in this testing is the
^-p (pessimistic elaboration order)^/PESSIMISTIC_ELABORATION_ORDER^
switch for
Normally the binder tries to find an order that has the best chance of
of avoiding elaboration problems. With this switch, the binder
plays a devil's advocate role, and tries to choose the order that
has the best chance of failing. If your program works even with this
switch, then it has a better chance of being error free, but this is still
not a guarantee.
For an example of this approach in action, consider the C-tests (executable tests) from the ACVC suite. If these are compiled and run with the default treatment, then all but one of them succeed without generating any error diagnostics from the binder. However, there is one test that fails, and this is not surprising, because the whole point of this test is to ensure that the compiler can handle cases where it is impossible to determine a correct order statically, and it checks that an exception is indeed raised at run time.
This one test must be compiled and run using the `-gnatE' switch, and then it passes. Alternatively, the entire suite can be run using this switch. It is never wrong to run with the dynamic elaboration switch if your code is correct, and we assume that the C-tests are indeed correct (it is less efficient, but efficiency is not a factor in running the ACVC tests.)
|[ < ]
|[ > ]
|[ << ]
|[ Up ]
|[ >> ]
|[ ? ]
|delorie software privacy
|Copyright © 2003 by The Free Software Foundation
|Updated Jun 2003


text:
If we find a pet at your adoption venue, can we take it home that day?
We suggest reading our Adoption Process document (Under the Adoption Tab) to better understand our requirements. Our screening process is intended to ensure these dogs and cats are never found in a city shelter again. This document explains the criteria that must be met in order to adopt, and when you can expect to receive the pet you've chosen.
How often do you hold adoptions?
We are Petsmart Partners and hold adoptions every Saturday from noon to 5PM at the Petsmart store in Rockwall, TX. Click on the Adoption Tab/Adoption Venue for store address and phone.
Success Stories
- Click here for Stella's staycation storyRead more
Follow us on Facebook

subset: commoncrawl