Version 1.2 of ais/ai-00325.txt
!standard 3.10 (01) 03-02-05 AI95-00325/01
!class amendment 03-02-05
!status work item 03-02-05
!status received 03-02-05
!priority Medium
!difficulty Hard
!subject Anonymous access types as function result types
!summary
This AI focuses strictly on issues relating to anonymous
access types as function result types. It only makes sense
if AI-00230 in some form is approved.
!problem
This proposal builds on AI-00230, by extending the advantages
of anonymous access types to function result types.
Because Ada has local access types, there needs to be a way to
remember the accessibility level of the object designated by
a reference across function return.
Because Ada has multiple storage pools, it is important that an
allocator of an anonymous access type allocate from the appropriate
storage pool.
!proposal
The "access_definition" syntactic category (see AI-00231) is permitted
for function result types. The type associated with the result type is
an anonymous access type, which permits implicit conversions from other
access types with appropriately compatible designated subtypes (as
defined by 4.6(13-17)).
The accessibility level of an anonymous access type is determined at the
time when the access_definition is elaborated. For a function result
type, this happens at the time of the function return, and may possibly
depend on information provided by the caller.
To be specific, the level of the returned value is the same as the level
of the type of the returned value, which must be shallower than the
level of the execution of the function (to avoid dangling references by
the caller). If the return expression is an allocator, the accessibility
level and storage pool for the allocator is determined by the context of
the call on the function. In particular, the storage pool used is the
one that would have been used had the allocator appeared at the poin of
the function call. (This rule is applied recursively for a chain of
calls.)
This implies that the call on a function with an anonymous access return
type must be passed in a storage pool and an accessibility level, and
must return both an access value and an accessibility level.
[Implementation NOTE: The implementation may implement the accessibility
level check either after returning from the call, or at the point of the
return statement, since it has enough information to do it there as
well.]
!wording
(See proposal.)
!example
!discussion
Implementing anonymous function result types is probably more work
than the other proposed uses for anonymous access types. However,
anonymous result types provide important
capabilities that are currently very difficult to accomplish.
First of all, one can define a function that constructs an object
(including an object of a limited type) in a storage pool determined
by the caller, including a "stackish" storage pool (i.e. one that
is cheap to reclaim). This kind of constructor is definitely
missing in Ada now. Currently, the access type, and hence the
storage pool, must be known inside the function that creates
an object. Secondly, there is no way to create a single function
that can be used both for creating a local object and a heap object
with similar efficiencies. With this proposal, the "constructor"
would look like this:
function Construct(...) return access T is
begin
...
return new T'(...);
end;
X : constant access T := Construct(...); --
Y : constant T_Ptr := Construct(...); --
Secondly, one could define a function that could return a reference to
an aliased component of an object that is itself passed in using an access
parameter. This would effectively allow a function to act as a "selector"
that can be used on the left hand side of an assignment when followed by
".all". E.g:
X : aliased Rec_With_Aliased_Component;
begin
Selected_Component(X'access).all := Y;
where Selected_Component is declared:
function Selected_Component(RP : access Rec_With_Aliased_Component)
return access Component_Type is
begin
return RP.Component'access;
end Selected_Component
And if we approve the "object.operation" syntax:
X.Selected_Component.all := Y;
presuming Selected_Component is declared in the same package as
Rec_With_Aliased_Component.
Implementation Issues:
There are some implementation issues associated with supporting function
returns. Basically it means that such a function has to use run-time
accessibility levels rather than static accessibility levels internally. Or
more precisely, it needs to use accessibility levels that are comparable with
those used by the caller. This need not be a huge burden. Probably the
simplest is to have the caller pass in a "caller" accessibility level to the
function, which the function then adds one to to use as its own accessibility
level.
[Some optimizations are possible: If there is only one access parameter, it
could use the accessibility level associated with that parameter as the
"caller" level (think about it ;-). If there are two or more access
parameters, it could use the max of them. At that point, it would be more
efficient to have the caller just pass in an extra parameter which is the
"true" caller accessibility level. If it is nested in a function that also
has access parameters, it is possible that it might have no access parameters,
in which case it would probably need a "caller" accessibility level passed in
as an additional parameter, though it could probably calculate it from the
accessibility level of the access parameter passed into the enclosing function.
Etc...]
!ACATS test
Tests should be created to check on the implementation of this feature.
!appendix
[... much interesting discussion elided ...] [See the appendex of AI-00230
for the interesting discussion.]
*************************************************************
From: Tucker Taft
Sent: Friday, February 1, 2002 11:54 AM
Here is an update to ai-00230 on anonymous access types.
I was able to resolve the problems that I had with them last time,
while eliminating the mind-bending named subtypes of anonymous access types,
but adding back components of an anonymous access type.
I think it all works safely and usefully now, especially presuming
the syntax for "access_definition" is generalized (see ai-231) to allow
control over nullness, and constantness of the designated object.
[See AI body for current proposal - Ed.]
*************************************************************
Questions? Ask the ACAA Technical Agent