comp.lang.ada
 help / color / mirror / Atom feed
* Elaboration worries
@ 2006-06-21 12:33 Alex R. Mosteo
  2006-06-21 18:01 ` Samuel Tardieu
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Alex R. Mosteo @ 2006-06-21 12:33 UTC (permalink / raw)


Hello,

I'm revisiting this topic in hope of enlightenment by someone that really
understand the dark magic behind elaboration. I've read the relevant
sections of the ARM but I can just grasp a more-or-less depth
understanding, of which details fade away with time.

From past discussions and from reading an old article of Mr. Dewar, my rule
of thumb is that you should

a) make your package Pure.
b) if not possible, make it Preelaborate.
c) if not possible, put an Elaborate_Body in the spec.

I was happy following this rule, but just recently I've started to
experiment with the -gnatwl switch, that warns when a "Elaborate_All" is
needed. I have two questions related with this. 

The first one is that I don't really grasp why a "Elaborate_All" could be
needed if one strictly follows the tree rules above.

The second one is this: by my observation of the gnat warnings, it seems
that the requirement for "Elaborate_All" is a "server side" one. However, I
must use the E_A in all "client side" units. This is because contrarily to
the abc) rule pragmas, that can refer to the package where they appear, E_A
can not.

Example: Package A causes a warning for E_A in all packages that use A. I
can't do nothing at A to remove the warning, but to put an E_A(A) in all
client packages. This seems strange to me.

A final note is that this second situation happens to me mostly with generic
units.

Thanks for any comments,

A. Mosteo.



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 12:33 Elaboration worries Alex R. Mosteo
@ 2006-06-21 18:01 ` Samuel Tardieu
  2006-06-21 20:34 ` Randy Brukardt
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Samuel Tardieu @ 2006-06-21 18:01 UTC (permalink / raw)


>>>>> "Alex" == Alex R Mosteo <devnull@mailinator.com> writes:

Alex> The first one is that I don't really grasp why a "Elaborate_All"
Alex> could be needed if one strictly follows the tree rules above.

Do you mean, you have at least a pragma Elaborate_Body in all your
packages?

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 12:33 Elaboration worries Alex R. Mosteo
  2006-06-21 18:01 ` Samuel Tardieu
@ 2006-06-21 20:34 ` Randy Brukardt
  2006-06-21 23:07   ` Samuel Tardieu
  2006-06-21 23:12   ` Robert A Duff
  2006-06-21 23:07 ` Robert A Duff
  2006-06-22 10:36 ` Alex R. Mosteo
  3 siblings, 2 replies; 14+ messages in thread
From: Randy Brukardt @ 2006-06-21 20:34 UTC (permalink / raw)


"Alex R. Mosteo" <devnull@mailinator.com> wrote in message
news:4fssh9F1ena5jU1@individual.net...
...
> From past discussions and from reading an old article of Mr. Dewar, my
rule
> of thumb is that you should
>
> a) make your package Pure.
> b) if not possible, make it Preelaborate.
> c) if not possible, put an Elaborate_Body in the spec.

Unfortunately, this rule of thumb is wrong (you probably got it from reading
the old article). Adacore later discovered that having Elaborate_Body in a
spec does not eliminate elaboration problems, and their modern versions of
GNAT don't make any recommendation for this. We were bitten rather badly by
this with Claw (which followed your list of recommendations quite closely).
I forget the exact reason that Elaborate_Body doesn't work, but the effect
is that you can't count on it to eliminate elaboration problems completely.

Effectively, if you do much of anything at elaboration time, you'll need
Elaborate_All in the clients for any packages that aren't at least
Preelaborate. There is nothing whatsoever that can be done for the service
packages that prevents that. (It's really a flaw in Ada, but one that cannot
be fixed without radical surgery and incompatibilities -- not an option
these days).

My personal rule of thumb is:
   (a) make your package Preelaborate if possible (Pure is so limited that
no real packages ever qualify) -- but this is usually impossible because I/O
and Calendar aren't Preelaborate. Which means that you can't trace or log a
Preelaborate package (well, there *is* one way to do it, but it adds runtime
overhead);
   (b) if not (a), try to avoid doing anything at elaboration time other
than use language-defined packages;
   (c) if not (b), then you have to add Elaborate_All for anything used at
elaboration time.

(c) usually happens when you have generic instantiations at the library
level, or you declare controlled objects at the library level. The latter
can be avoided, the former obviously can't.

I've long since given up running code (the 'begin' part of a package body)
at elaboration time; there always seems to be some reason that you have
initialization dependencies that aren't encoded in the elaboration order
(for instance, the need to load parameters from the registry or a
configuration file before starting a subsystem). I use appropriate
initialization routines (and often checks for calls to other routines in the
package that the initialization has been properly called).

Hope this helps.

                         Randy.





^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 12:33 Elaboration worries Alex R. Mosteo
  2006-06-21 18:01 ` Samuel Tardieu
  2006-06-21 20:34 ` Randy Brukardt
@ 2006-06-21 23:07 ` Robert A Duff
  2006-06-22  2:24   ` Matthew Heaney
  2006-06-22 10:36 ` Alex R. Mosteo
  3 siblings, 1 reply; 14+ messages in thread
From: Robert A Duff @ 2006-06-21 23:07 UTC (permalink / raw)


"Alex R. Mosteo" <devnull@mailinator.com> writes:

> a) make your package Pure.
> b) if not possible, make it Preelaborate.
> c) if not possible, put an Elaborate_Body in the spec.
> 
> I was happy following this rule, but just recently I've started to
> experiment with the -gnatwl switch, that warns when a "Elaborate_All" is
> needed. I have two questions related with this. 
> 
> The first one is that I don't really grasp why a "Elaborate_All" could be
> needed if one strictly follows the tree rules above.

I don't think you can follow those three rules in all cases,
because they place restrictions on the code you can write.
For example, Elab_Body prevents a package body from with-ing
its children.

There's a good description of elab issues in the GNAT docs.

> The second one is this: by my observation of the gnat warnings, it seems
> that the requirement for "Elaborate_All" is a "server side" one. However, I
> must use the E_A in all "client side" units. This is because contrarily to
> the abc) rule pragmas, that can refer to the package where they appear, E_A
> can not.

Yes, that is a pain.

> Example: Package A causes a warning for E_A in all packages that use
> A.


No -- only if they use A at elaboration time.

>... I
> can't do nothing at A to remove the warning, but to put an E_A(A) in all
> client packages. This seems strange to me.

Yes, it is strange.

> A final note is that this second situation happens to me mostly with generic
> units.

Yes, that's because generic instantiations are usually at library level,
and are therefore elaborated at library package elab time.

- Bob



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 20:34 ` Randy Brukardt
@ 2006-06-21 23:07   ` Samuel Tardieu
  2006-06-22 23:06     ` Randy Brukardt
  2006-06-21 23:12   ` Robert A Duff
  1 sibling, 1 reply; 14+ messages in thread
From: Samuel Tardieu @ 2006-06-21 23:07 UTC (permalink / raw)


>>>>> "Randy" == Randy Brukardt <randy@rrsoftware.com> writes:

Randy> try to avoid doing anything at elaboration time other than
Randy> use language-defined packages;

There are cases where this is quite impractical; for example, when
using the Ravenscar profile, tasks cannot be created dynamically and
will be started at elaboration time. Using a "start" protected object
can be used as a workaround to limit their execution until after the
main program has been launched.

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 20:34 ` Randy Brukardt
  2006-06-21 23:07   ` Samuel Tardieu
@ 2006-06-21 23:12   ` Robert A Duff
  2006-06-22 23:09     ` Randy Brukardt
  1 sibling, 1 reply; 14+ messages in thread
From: Robert A Duff @ 2006-06-21 23:12 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> I forget the exact reason that Elaborate_Body doesn't work, but the effect
> is that you can't count on it to eliminate elaboration problems completely.

Hmm.  Dispatching calls at elab time, maybe?  Elab_Body does ensure that
the body will be elaborated before all clients.

>    (a) make your package Preelaborate if possible (Pure is so limited that
> no real packages ever qualify) -- but this is usually impossible because I/O
> and Calendar aren't Preelaborate. Which means that you can't trace or log a
> Preelaborate package (well, there *is* one way to do it, but it adds runtime
> overhead);

I have put debug output code in Pure and Preelab packages by "cheating".
Like this: write a simple I/O package (I like to avoid the complexity
of Text_IO).  Use pragma Export(Ada) on all of its procedures.
Then write another package that declares all the same procedures,
with pragma Import(Ada), and put pragma Pure in that.

This is cheating, so I only do it for temporary debugging output.

- Bob



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 23:07 ` Robert A Duff
@ 2006-06-22  2:24   ` Matthew Heaney
  0 siblings, 0 replies; 14+ messages in thread
From: Matthew Heaney @ 2006-06-22  2:24 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:

> Yes, that's because generic instantiations are usually at library level,
> and are therefore elaborated at library package elab time.

Just to add to what Bob says here (and to paraphrase what he has recommended in
other threads on this topic), you need to pragma Elaborate_All whenever you do
an instantiation, e.g.

with GP;
pragma Elaborate_All (GP);

package Q is
   pragma Preelaborate; -- or whatever
   package P is new GP (...);
   ...
end Q;

with GR;
pragma Elaborate_All (GR);

package body Q is
  package R is new GR (...);
  ...
end Q;


The Charles library and the GNAT implementation of the standard container
library are implemented like that, with an Elaborate_All on the generic package
being instantiated.

Note that I don't usually bother using pragma Elaborate_Body unless I need to
either force a body for a spec that otherwise wouldn't require a body, or
because the body has state.  In the latter case you want to ensure that the
package state is fully elaborated before any operations in that package are
called (by some other package during its own elaboration).

Of course if, during elaboration of a package, the package calls an operation
in some other package, then the package must Elaborate_All on the called
package.

Normally you want pragma Elaborate_All, but pragma Elaborate is still useful
occasionally, when elaborating packages with mutual dependencies.



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 12:33 Elaboration worries Alex R. Mosteo
                   ` (2 preceding siblings ...)
  2006-06-21 23:07 ` Robert A Duff
@ 2006-06-22 10:36 ` Alex R. Mosteo
  2006-06-22 16:25   ` Alex R. Mosteo
  2006-06-22 23:31   ` Randy Brukardt
  3 siblings, 2 replies; 14+ messages in thread
From: Alex R. Mosteo @ 2006-06-22 10:36 UTC (permalink / raw)


Alex R. Mosteo wrote:

> Hello,
> 
> I'm revisiting this topic in hope of enlightenment by someone that really
> understand the dark magic behind elaboration. I've read the relevant
> sections of the ARM but I can just grasp a more-or-less depth
> understanding, of which details fade away with time.

Many thanks for all the clarifications and comments, they're really useful
to me and will be of great aid when reading the RM again.

I'm also interested in the "cheating" for I/O, since this seems really a
weak spot. Any other cheats besides the one mentioned by Mr.Duff?



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-22 10:36 ` Alex R. Mosteo
@ 2006-06-22 16:25   ` Alex R. Mosteo
  2006-06-22 23:31   ` Randy Brukardt
  1 sibling, 0 replies; 14+ messages in thread
From: Alex R. Mosteo @ 2006-06-22 16:25 UTC (permalink / raw)


Alex R. Mosteo wrote:

> Alex R. Mosteo wrote:
> 
>> Hello,
>> 
>> I'm revisiting this topic in hope of enlightenment by someone that really
>> understand the dark magic behind elaboration. I've read the relevant
>> sections of the ARM but I can just grasp a more-or-less depth
>> understanding, of which details fade away with time.
> 
> Many thanks for all the clarifications and comments, they're really useful
> to me and will be of great aid when reading the RM again.
> 
> I'm also interested in the "cheating" for I/O, since this seems really a
> weak spot. Any other cheats besides the one mentioned by Mr.Duff?

For the record, I've found this link a interesting read in relation with
this topic:

http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00366.TXT?rev=1.19



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 23:07   ` Samuel Tardieu
@ 2006-06-22 23:06     ` Randy Brukardt
  2006-06-23 18:42       ` Samuel Tardieu
  0 siblings, 1 reply; 14+ messages in thread
From: Randy Brukardt @ 2006-06-22 23:06 UTC (permalink / raw)


"Samuel Tardieu" <sam@rfc1149.net> wrote in message
news:87odwmcdku.fsf@willow.rfc1149.net...
> >>>>> "Randy" == Randy Brukardt <randy@rrsoftware.com> writes:
>
> Randy> try to avoid doing anything at elaboration time other than
> Randy> use language-defined packages;
>
> There are cases where this is quite impractical; for example, when
> using the Ravenscar profile, tasks cannot be created dynamically and
> will be started at elaboration time. Using a "start" protected object
> can be used as a workaround to limit their execution until after the
> main program has been launched.

Which is why I said "try to avoid", not just "avoid". It's hard to avoid
library-level generic instantiations, for instance. OTOH, I was under the
impression that most Ravenscar programs used what is now known as the
"Concurrent" elaboration policy (see H.6 in the Ada 2005 RM). That prevents
tasks from being started until elaboration of library units is finished. So
the problem is less that you have to do things at elaboration time in
Ravenscar, and more that Ravenscar is incompatible with the traditional Ada
elaboration model.

                               Randy.





^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-21 23:12   ` Robert A Duff
@ 2006-06-22 23:09     ` Randy Brukardt
  0 siblings, 0 replies; 14+ messages in thread
From: Randy Brukardt @ 2006-06-22 23:09 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
news:wcck67aumqe.fsf@shell01.TheWorld.com...
> "Randy Brukardt" <randy@rrsoftware.com> writes:
...
> >    (a) make your package Preelaborate if possible (Pure is so limited
that
> > no real packages ever qualify) -- but this is usually impossible because
I/O
> > and Calendar aren't Preelaborate. Which means that you can't trace or
log a
> > Preelaborate package (well, there *is* one way to do it, but it adds
runtime
> > overhead);
>
> I have put debug output code in Pure and Preelab packages by "cheating".

True, you can leave the language if you like, or lie to the compiler (I
guess you'd say what you are doing is the latter; I would call it the
former), but I was thinking of ways that don't require such underhandedness
and can be used in production code.

                           Randy.





^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-22 10:36 ` Alex R. Mosteo
  2006-06-22 16:25   ` Alex R. Mosteo
@ 2006-06-22 23:31   ` Randy Brukardt
  1 sibling, 0 replies; 14+ messages in thread
From: Randy Brukardt @ 2006-06-22 23:31 UTC (permalink / raw)


"Alex R. Mosteo" <devnull@mailinator.com> wrote in message
news:4fva3aF1lff5cU1@individual.net...
...
> I'm also interested in the "cheating" for I/O, since this seems really a
> weak spot. Any other cheats besides the one mentioned by Mr.Duff?

Well, I don't cheat, rather I pass in the logging routines to the
Preelaborated packages. (This will also work for Pure in Ada 2005.)

First, I declare a logging access type:

    type Logger_Access is access procedure (Message : in String);
        -- Write a line to the log (if any).

And then all of the routines that need to do logging including a Logger
parameter:
    Logger : in Logger_Access := null

If Logger is null, nothing is written. Logger_Access is defined so that the
profile matches Ada.Text_IO.Put_Line for unit debugging, and it matches the
profile of the logging routines that we usually use.

Now, you do have to pass this through all of the calls inside of
Preelaborated packages. Once you get to a normal package, you can just
provide the appropriate logger routine:
      ...
      Logger => Ada.Text_IO.Put_Line'Access);

And this provides a way to access "normal" stuff from Preelaborared
packages. Of course, it only works if the number of such things is rather
limited.

I should point out that I started using this because I had a need to use
different logging techniques in different programs that depended on the same
shared library. The fact that it let some of the libraries be Preelaborated
was a bonus.

                                Randy.







^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-22 23:06     ` Randy Brukardt
@ 2006-06-23 18:42       ` Samuel Tardieu
  2006-06-23 19:54         ` Randy Brukardt
  0 siblings, 1 reply; 14+ messages in thread
From: Samuel Tardieu @ 2006-06-23 18:42 UTC (permalink / raw)


>>>>> "Randy" == Randy Brukardt <randy@rrsoftware.com> writes:

Randy> OTOH, I was under the impression that most Ravenscar programs
Randy> used what is now known as the "Concurrent" elaboration policy
Randy> (see H.6 in the Ada 2005 RM). That prevents tasks from being
Randy> started until elaboration of library units is finished.

You mean "Sequential" rather than "Concurrent"?

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Elaboration worries
  2006-06-23 18:42       ` Samuel Tardieu
@ 2006-06-23 19:54         ` Randy Brukardt
  0 siblings, 0 replies; 14+ messages in thread
From: Randy Brukardt @ 2006-06-23 19:54 UTC (permalink / raw)


"Samuel Tardieu" <sam@rfc1149.net> wrote in message
news:87wtb7btnc.fsf@willow.rfc1149.net...
> >>>>> "Randy" == Randy Brukardt <randy@rrsoftware.com> writes:
>
> Randy> OTOH, I was under the impression that most Ravenscar programs
> Randy> used what is now known as the "Concurrent" elaboration policy
> Randy> (see H.6 in the Ada 2005 RM). That prevents tasks from being
> Randy> started until elaboration of library units is finished.
>
> You mean "Sequential" rather than "Concurrent"?

Yes, of course. Sorry for any confusion.

                    Randy.





^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2006-06-23 19:54 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-21 12:33 Elaboration worries Alex R. Mosteo
2006-06-21 18:01 ` Samuel Tardieu
2006-06-21 20:34 ` Randy Brukardt
2006-06-21 23:07   ` Samuel Tardieu
2006-06-22 23:06     ` Randy Brukardt
2006-06-23 18:42       ` Samuel Tardieu
2006-06-23 19:54         ` Randy Brukardt
2006-06-21 23:12   ` Robert A Duff
2006-06-22 23:09     ` Randy Brukardt
2006-06-21 23:07 ` Robert A Duff
2006-06-22  2:24   ` Matthew Heaney
2006-06-22 10:36 ` Alex R. Mosteo
2006-06-22 16:25   ` Alex R. Mosteo
2006-06-22 23:31   ` Randy Brukardt

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