From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!nntp-feed.chiark.greenend.org.uk!ewrotcd!newsfeed.xs3.de!io.xs3.de!news.jacob-sparre.dk!franka.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Elaboration in generic package Date: Wed, 12 Apr 2017 17:29:03 -0500 Organization: JSA Research & Innovation Message-ID: References: NNTP-Posting-Host: rrsoftware.com X-Trace: franka.jacob-sparre.dk 1492036144 12717 24.196.82.226 (12 Apr 2017 22:29:04 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Wed, 12 Apr 2017 22:29:04 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Xref: news.eternal-september.org comp.lang.ada:46581 Date: 2017-04-12T17:29:03-05:00 List-Id: "Simon Wright" 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.