Prev: Tiny mistaken on an AdaPower page
Next: Initialization and Finalization of limited object "returned"by a function
From: Randy Brukardt on 11 Feb 2010 19:44 "Adam Beneschan" <adam(a)irvine.com> wrote in message news:d1d2586a-2f70-491a-8a12-01abae4ab6f5(a)t34g2000prm.googlegroups.com... .... > Yes, I believe that's right, and it's spelled out clearly in the RM, > in sections 7.6(17.1/3-17.11/3 and especially 17.7/3), 6.5(5.8/3), > 6.5(23/2), 7.6(4), and 3.10.2(10.1/2). Whether Adam was being sarastic or not, note that this semantics was totally rewritten after Amendment 1 was finished. And Adam is reading the new, much clearer text (that's relative, of course); the old text left so many questions unanswered that we gave up and started over. (Bob did much of the heavy lifting on that.) Summary: He's looking at the draft Ada 2012 standard and not the Ada 2005 one. Ada compilers are supposed to follow the new wording (it is a Binding Interpretation -- essentially a bug fix to the Standard), but there is no reason to assume that they do. Randy.
From: Adam Beneschan on 11 Feb 2010 20:05 On Feb 11, 2:49 pm, Hibou57 (Yannick Duchêne) <yannick_duch...(a)yahoo.fr> wrote: > On 11 fév, 22:51, Adam Beneschan <a...(a)irvine.com> wrote:> For an extended return, > > > return R : T; > > > R is not a local variable, and it isn't "assigned" into the anonymous > > object; thus, there's no Adjust, and R is not finalized when the > > function returns > > Yes > > > (but the anonymous object will be finalized later, > > Which anonymous object ? Any time you call a function, the language semantics say that there is a "result object" to hold the function result. The function is called and puts its result in the result object. The reason the language calls it a distinct object is so that it can define when Adjusts and finalizations take place for this object. I may have erred by calling it an anonymous object. In Ada 95, I believe it was referred to as an anonymous object. In Ada 2005, if you use the extended return syntax, this gives a name to the result object (as Bob said), so maybe it's wrong to call it "anonymous", although there are parts of the RM that refer to "the anonymous object representing the result of a function call" or words to that effect. In any case, at the place where the function is called, you can't refer to this result object by any name. My earlier post may have been confusing because I was referring to two separate parts of the function call process: (1) how the value gets INTO the result object and (2) what the caller does with the result object AFTER the function is finished. For #1, when the function says return EXPR; then EXPR is assigned into the result object (which means that an Adjust has to be done), *unless* the result object gets built in place, which is always the case if EXPR is a function call and the type is limited. But if the function says return NAME : TYPE [do ... end return]; then NAME is a name that *refers* to the result object; NAME does *not* declare another object that will get assigned to the result object as in the earlier example. For #2, if you say X : T := Func(...); The call to Func means that there is a "result object". When Func is called, the value gets put into the result object somehow, as mentioned above. Then, if X is not built in place, the result object is copied to X, which means that an Adjust is done, and then the result object is finalized. However, if X *is* built in place (as it must be if T is limited), then the call to Func puts a value into the result object; and then after that point, X starts "magically" referring to that result object. There's no copying, and no Finalize. That's what the RM means by "mutating into". Yes, the language is a bit weird, and I know it was difficult for the ARG to find the right words to express what was supposed to happen. Anyway, the end result of all this is that, for a limited type (or in any other case where X is built in place), there isn't supposed to be any finalization until X disappears. In your case, if you're seeing your A_Type get finalized while Tested_Interface still exists, this is incorrect behavior. Hope this clears things up. If instead I've just created more confusion, I apologize and promise to refrain from making things worse by trying to explain myself any more. -- Adam
From: Hibou57 (Yannick Duchêne) on 11 Feb 2010 21:35 On 12 fév, 02:05, Adam Beneschan <a...(a)irvine.com> wrote: > Hope this clears things up. If instead I've just created more > confusion, I apologize and promise to refrain from making things worse > by trying to explain myself any more. > > -- Adam You're joking, aren't you ? You did not really though this words ... Well, the story continues. First of all, I apologize to not have read all comments so far (not entirely), which will be done whatever. Here is a second test I've drove, to be really sure about what's going on. Here is the plan : start from a simple case, and follow a path to a similar case to the one which gave the doubts exposed in the initial post of this thread. This comes into six simple samples, A to F. Simplified on purpose to ease quick overview (no more explicit spy, add it yourself if you want to the check what's asserted). A single comment in each heading explain the difference of one test compared to its predecessor, as well the observation made (which I made with a spy which is dropped from this samples, for the reason given above). The trouble occurs at step F. I will post each samples on its own post, to ease quoting (hope this sequence of six posts will not be too much annoying). Here we go ...
From: Hibou57 (Yannick Duchêne) on 11 Feb 2010 21:36 procedure A is -- Defines a limited type returned by a function. -- Observations : Entity is initialized when it is -- created an New_Limited, and finalized when its -- scope (that is, A) is terminated. -- Conclusion : everything's fine. package P is type Limited_Type is limited null record; function New_Limited return Limited_Type; end P; package body P is function New_Limited return Limited_Type is begin return R : Limited_Type do null; end return; end; end P; Entity : P.Limited_Type := P.New_Limited; begin null; end A;
From: Hibou57 (Yannick Duchêne) on 11 Feb 2010 21:36
procedure B is -- Variation from A : New_Limited now -- relies on an intermediate function, -- Pre_New_Limited. -- Observations : still fine. package P is type Limited_Type is limited null record; function New_Limited return Limited_Type; end P; package body P is function Pre_New_Limited return Limited_Type is begin return R : Limited_Type do null; end return; end; function New_Limited return Limited_Type is begin return R : Limited_Type := Pre_New_Limited do null; end return; end; end P; Entity : P.Limited_Type := P.New_Limited; begin null; end B; |