Re: Question about circular elaboration order error (GNAT).

"Peter" == Peter C Chapin <pchapin@xxxxxxxxx> writes:

Peter> I don't understand where the circularity is coming from. Isn't
Peter> the following elaborate order acceptable:

No. pragma Elaborate_All is transitive, and forces the elaboration of
Parent body (since Parent.Child has an implicit dependency on Parent)
before... Parent body elaboration. Hence the circular elaboration

But you can fix the situation by providing GNAT with the necessary
elaboration information:

- put a "pragma Elaborate (Parent.Child)" in Parent body to indicate
that Parent elaboration requires Parent.Child to be elaborated; this
pragma isn't transitive, so you have to ensure that subprograms of
Parent.Child called during the elaboration of Parent do not
themselves require that other packages be elaborated first, or add
the required pragma;

- put a "pragma Elaborate_Body" in Parent.Child spec if you know
that this package is likely to be called during the elaboration of
other packages; this requires that the body be elaborated just
after the spec.

Using only the "pragma Elaborate_Body" will not be enough for GNAT, so
the "pragma Elaborate" is required. That is because GNAT is
overcautious and adds implicit "pragma Elaborate_All" unless you
provide explicit "pragma Elaborate".

Note that having GNAT be overcautious by default is actually a good
thing: I spent three hours two weeks ago debugging a tricky
elaboration problem in a software written for an embedded system. The
original author incorrectly used "pragma Elaborate". Had he done
nothing, GNAT would have warned him about the dangerous situation.

I hope this clarifies things.

Samuel Tardieu -- sam@xxxxxxxxxxx --