From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Elaboration in generic package
Date: Wed, 12 Apr 2017 17:29:03 -0500
Date: 2017-04-12T17:29:03-05:00 [thread overview]
Message-ID: <ocm9ng$cdd$1@franka.jacob-sparre.dk> (raw)
In-Reply-To: ly60i9bf06.fsf@pushface.org
"Simon Wright" <simon@pushface.org> wrote in message
news:ly60i9bf06.fsf@pushface.org...
>A StackOverflow user raises this problem
> (http://stackoverflow.com/q/43349462/40851). The code:
>
> generic
> Top_M : Positive;
> package Mystic is
> type T is private;
> procedure Info;
> private
> type Table is array (Positive range <>) of Positive;
> function reallyComplicatedFunction(x : Positive) return Table;
>
> mytable : constant Table :=
> reallyComplicatedFunction(top_m); --<<<<<
> -- I will need mytable for calculations later
>
> type T is array (mytable'Range) of Natural;
> -- T is very different from Table, except they share their Range
> end Mystic;
>
> They wonder how the call to reallyComplicatedFunction at line 10
> succeeds, given it looks like its body hasn't been seen yet (ARM
> 3.11(10)). Indeed, if I make Mystic non-generic (Top_M is a constant)
> GNAT tells me
>
> kryptozoon.ada:12:33: warning: cannot call "reallyComplicatedFunction"
> before body seen
> kryptozoon.ada:12:33: warning: Program_Error will be raised at run time
>
> and then, sure enough,
>
> raised PROGRAM_ERROR : kryptozoon.ada:12 access before elaboration
>
> Is it possible that the answer is ARM 3.11(13), "For the instantiation
> of a generic unit that has a body, a check is made that this body is
> already elaborated."? If so, this seems surprising.
Thoughts, not answers:
(1) GNAT doesn't follow the RM vis-a-vis elaboration checks unless -gnatE is
used, so unless that it is the case, there's really nothing to talk about.
The RM has nothing to say really about non-standard modes.
(2) 3.11(10) and 3.11(13) are independent checks; I don't see anything that
suggests that making the one check eliminates the other.
(3) There are other cases where there are multiple elaboration checks
(AI95-00064-1 discusses one such case).
So my gut feeling is that there should be an elaboration check (and
hopefully a warning that the check will always fail). That suggests that the
OP has found a compiler bug, nothing more.
OTOH, I remember spending quite a bit of effort eliminating elaboration
checks in cases where they could not fail. So I may have forgotten
something.
Randy.
P.S. On second thought, it seems necessary to have an elaboration check in
this case, since the body could depend on something not elaborated at the
point of call. For instance:
with My_Random;
package body Mystic is
Seed : Natural := My_Random; -- A function call.
function reallyComplicatedFunction (TM : Positive) return Table is
begin
if TM > Seed then -- Oops!
...
end if;
end reallyComplicatedFunction;
end Mystic;
Since Ada elaborates items linearly, the instance elaboration of Mystic will
call reallyComplicatedFunction before Seed is elaborated -- meaning the body
would be depending on something uninitialized. That's what subprogram
elaboration checks are designed to prevent. Ergo, there must be a check in
this case (regardless of the actual body, of course). (The generic body
check is something different; it makes sure that the objects that the body
can reference are elaborated before the instance of the body is elaborated.
For "normal" packages, that is done statically by the rules for with
clauses, but a generic unit is different in that regard.)
Randy.
next prev parent reply other threads:[~2017-04-12 22:29 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-12 19:30 Elaboration in generic package Simon Wright
2017-04-12 22:29 ` Randy Brukardt [this message]
2017-04-13 7:19 ` Simon Wright
2017-04-13 15:38 ` marciant
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox