From: Natasha Kerensikova <lithiumcat@instinctive.eu>
Subject: Generic instantiation before actual subprogram body
Date: Thu, 4 Dec 2014 08:48:58 +0000 (UTC)
Date: 2014-12-04T08:48:58+00:00 [thread overview]
Message-ID: <slrnm80802.nrc.lithiumcat@nat.rebma.instinctive.eu> (raw)
Hello,
I have fallen into the pattern of refactoring common using generics
instead of cut-and-paste. One of my earliest example of this is
https://github.com/faelys/natools/blob/trunk/src/natools-s_expressions-interpreter_loop.adb
I think it's a good thing, even for only a few tens of lines of code,
mostly for readers who discover the code: explicit common patterns reduce
(I think) the cognitive overhead.
Please enlighten me if I'm wrong on this.
At some early point when I used the pattern, I encountered a GNAT
warning telling that a particular generic instantiation would raise
Program_Error at run-time because the body of actual subprograms in the
instantiation were found later in the source text.
Since then, I always put instantiations after the bodies of the actual
subprograms, even though it makes it a bit awkward.
A lot of time passed, and I'm now feeling the need to refactor a
cut-and-paste-able code structure involved in a recursive cycle.
Recursivity means at some point something has to be called before its
body. This led me to question that instantiation-before-body warning,
so I started experimented, but I couldn't reproduce the warning.
My question is now, in which set of circumstances is it allowed (or
forbidden) to instantiate a generic with a subprogram whose body has not
yet been seen by the compiler?
I'm pretty sure I was using an older GNAT in Ada 2005 mode back then,
could it be something that has changed in Ada 2012?
I tried to read the ARM and then the AARM, on chapters related to
generic instantiation and/or subprogram elaboration (I can't think of
any not-elaboration-related reason to raise Program_Error because of
subprogram body position in the source). I also tried reading GCC
sources, looking for "Program_Error [" and "body seen". However all
these resources are way out of my depth, so I'm asking here.
On a related but almost out-of-topic point, I have always instantiated
generic on a nesting level as shallow as possible. This is due to some
superstitious fear about trampolines and accessibility levels and a few
other nesting-related concept I don't understand.
In the particular case of my alternative-to-cut-and-paste generics, it's
often a generic procedure, whose instances are each called only once, in
a public subprogram whose body consists of almost only the generic
instance call, sometimes with a little bit of argument shuffling or type
adjustments to fit the generic model when the API has a slightly
different logic.
For example I have somewhere code similar to:
package body Whatever is
procedure Append (...);
procedure Render_Page_Element (...);
procedure Render_Page is new Natools.S_Expressions.Interpreter_Loop
(Output_Accumulator, Page_Type, Render_Page_Element, Append);
procedure Public_Render
(Page : in Page_Type;
Output : in out Output_Accumulator;
Template : in out Natools.S_Expressions.Lockable.Descriptor'Class) is
begin
Render_Page (Template, Output, Page);
end Public_Render;
end Whatever
Wouldn't it be better in such a case to instantiate the generic inside
Public_Render? That would solve any elaboration issue, and that would
limit the scope of the generic instance to where it is actually use,
which I find is generally a good guideline to follow.
I guess the compiler can easily tell there is no special nesting
mechanism needed, since all actual parameters have a large scope.
Is there any particular rational reason to prefer top-level
instantiation to nested instantiation, or vice versa?
Thanks in advance for your insights,
Natasha
next reply other threads:[~2014-12-04 8:48 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-04 8:48 Natasha Kerensikova [this message]
2014-12-04 9:31 ` Generic instantiation before actual subprogram body J-P. Rosen
2014-12-04 10:03 ` Natasha Kerensikova
2014-12-04 10:40 ` Georg Bauhaus
2014-12-04 14:12 ` J-P. Rosen
2014-12-04 15:34 ` Robert A Duff
2014-12-04 15:49 ` Robert A Duff
2014-12-04 22:49 ` Randy Brukardt
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox