Version 1.1 of ais/ai-00325.txt

Unformatted version of ais/ai-00325.txt version 1.1
Other versions for file 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
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.
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.
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.]
(See proposal.)
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(...); -- Create on the stack
Y : constant T_Ptr := Construct(...); -- Create in T_Ptr'Storage_Pool
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;
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...]

[... 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