From: Randy Brukardt on
"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
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
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
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
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;