comp.lang.ada
 help / color / mirror / Atom feed
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.



  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