comp.lang.ada
 help / color / mirror / Atom feed
From: Robert A Duff <bobduff@shell01.TheWorld.com>
Subject: Re: Elaboration order handling (Was: Bug in 'gnatmake')
Date: Thu, 20 Jun 2013 11:11:11 -0400
Date: 2013-06-20T11:11:11-04:00	[thread overview]
Message-ID: <wccd2rgrf5c.fsf@shell01.TheWorld.com> (raw)
In-Reply-To: kptkek$1e2$1@dont-email.me

Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:

> Since we're discussing elaboration order, there's a case that I wonder about:

A case of mutually-recursive packages.  That's unusual, because it's
usually better to design software in layers, where higher layers
use the lower layers, but not vice-versa.

But sometimes such mutually-dependent packages are exactly the
right thing.

> with B;
>
> package A is
>    function F (I : Integer) return B.Thing;
>
>    function R return Integer;
> end A;
>
> package body A is
>    function F (I : Integer) return B.Thing is
>       -- null;
>    begin -- F
>       return B.To_Thing (I);
>    end F;
>
>    function R return Integer is
>       -- null;
>    begin -- R
>       return 7;
>    end R;
> end A;
>
> package B is
>    type Thing is private;
>
>    function To_Thing (I : Integer) return Thing;
> private -- B
>    type Thing is new Integer;
> end B;
>
> with A;
>
> package body B is
>    function To_Thing (I : Integer) return Thing is
>       -- null;
>    begin -- To_Thing
>       return Thing (I);
>    end To_Thing;
>
>    C : constant Integer := A.R;
> end B;

In standard Ada, the above is perfectly legal, and does not
raise Program_Error.

> It seems to me there's a valid elaboration order for these:
>
> * spec of B
> * spec of A
> * body of A
> * body of B

Yes, and that is the only order allowed by the RM.

> I've never been able to get such code to bind, though. Is there some way
> to get this accepted, or is it illegal Ada?

Without -gnatE, GNAT will complain about an elaboration cycle,
because it is inserting an implicit "pragma Elaborate_All(A);"
on the body of B.  It does that because it's trying to preserve
abstraction -- it wants the code to work no matter what
A.R does (it's not looking at the body of A.R while compiling
body of B).  In fact, A.R could have called A.F, in which case
the program is broken -- the only allowed order causes Program_Error
in standard Ada, and the whole point of the not-gnatE mode is
to do all such run-time checks statically.
Imagine adding that call to A.F during maintenance.

And the reason the implicit pragma causes a cycle is that 
Elaborate_All is transitive -- it requires the body of
B to be elaborated before the body of B, which is impossible.

But you've got mutual recursion here, so A and B are necessarily
tightly coupled, and you, the programmer, can know that A.R does
NOT call anything in B.  In that case, you can solve the problem
by putting "pragma Elaborate(A);" on the body of B.  GNAT uses
that Elaborate *instead* of the implicit Elaborate_All, and Elaborate
is nontransitive, so it all works, using the order you showed above.

But be careful:  If you later change A.R to call A.F, you'll be
in trouble.

The other way to get this example to work is to use -gnatE.
I don't recommend that.

- Bob

P.S. I don't like your convention of putting "-- null;" in empty
declarative parts!  Comments should impart useful information,
and empty declarative parts are nothing special, and anyway,
I can see it's empty without a comment.

  parent reply	other threads:[~2013-06-20 15:11 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-17 10:57 Range check for type 'Integer' Peter Brooks
2013-06-17 11:23 ` Simon Clubley
2013-06-17 11:54   ` Simon Wright
2013-06-17 12:55   ` Peter Brooks
2013-06-17 13:28     ` Shark8
2013-06-17 13:45       ` Peter Brooks
2013-06-17 21:16         ` Shark8
2013-06-18 10:48     ` Stephen Leake
2013-06-17 12:46 ` Dmitry A. Kazakov
2013-06-17 13:23 ` Bug in 'gnatmake' (Was: Range check for type 'Integer') Jacob Sparre Andersen
2013-06-17 13:32   ` Bug in 'gnatmake' Jacob Sparre Andersen
2013-06-17 16:50   ` Bug in 'gnatmake' (Was: Range check for type 'Integer') Robert A Duff
2013-06-17 19:15     ` Peter Brooks
2013-06-17 21:09       ` Shark8
2013-06-17 21:22       ` Jeffrey Carter
2013-06-18  1:21         ` Peter Brooks
2013-06-18  6:33           ` Jeffrey Carter
2013-06-18  7:29       ` Georg Bauhaus
2013-06-17 18:49   ` Bug in 'gnatmake' Simon Wright
2013-06-18  9:09     ` Elaboration order handling (Was: Bug in 'gnatmake') Jacob Sparre Andersen
2013-06-18 17:09       ` Robert A Duff
2013-06-18 22:52         ` Adam Beneschan
2013-06-19  1:21           ` Jeffrey Carter
2013-06-19 12:38             ` Robert A Duff
2013-06-19 20:43               ` Georg Bauhaus
2013-06-20  0:37                 ` Robert A Duff
2013-06-20 19:56                   ` Georg Bauhaus
2013-06-19 12:22           ` Robert A Duff
2013-06-19 15:46             ` Adam Beneschan
2013-06-19 16:41               ` Robert A Duff
2013-06-19 20:47               ` Georg Bauhaus
2013-06-19 21:36                 ` Adam Beneschan
2013-06-20  0:57                 ` Robert A Duff
2013-06-20  1:09                   ` Jeffrey Carter
2013-06-20  2:29                     ` Adam Beneschan
2013-06-20  6:08                       ` Jeffrey Carter
2013-06-20 15:11                     ` Robert A Duff [this message]
2013-06-21  5:26                       ` Jeffrey Carter
2013-06-21 15:48                         ` Adam Beneschan
2013-06-21 18:35                           ` Jeffrey Carter
2013-06-21 19:10                             ` Robert A Duff
2013-06-21 21:27                               ` Jeffrey Carter
2013-06-21 20:43                             ` Adam Beneschan
2013-06-21 21:44                               ` Jeffrey Carter
2013-06-21 23:47                                 ` Robert A Duff
2013-06-23 14:43                                   ` AdaMagica
2013-06-21 18:58                         ` null declarative parts (was: Re: Elaboration order handling) Robert A Duff
2013-06-21 20:42                           ` null declarative parts Georg Bauhaus
2013-06-20  2:11                   ` Elaboration order handling (Was: Bug in 'gnatmake') Adam Beneschan
2013-06-20 14:44                     ` Robert A Duff
2013-06-20 11:24                   ` G.B.
2013-06-20 15:23                     ` Robert A Duff
2013-06-19 21:00             ` Georg Bauhaus
2013-06-19 22:26             ` Randy Brukardt
2013-06-20  0:31               ` Robert A Duff
2013-06-20 21:36                 ` Randy Brukardt
2013-06-19 13:07         ` Bill Findlay
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox