Version 1.3 of ais/ai-00404.txt
!standard 3.10(6/2) 05-02-13 AI95-00404/02
!class amendment 05-01-28
!status work item 05-01-28
!status received 05-01-28
!subject Not null and all in access parameters and types
Not null is implicit, but may be given explicitly, for controlling
access parameters and results. When defined by a renaming or
a generic instantiation, the controlling access parameters and
results must be null excluding.
All is not permitted as a general access modifier for anonymous access
The current proposal for Ada 2005 permits the specification of not null
for controlling access parameters even though they have to be not null
anyway. Similarly it permits the specification of all in anonymous
access types even though they never are pool specific and so all is
superfluous. This provides the user with several different ways of
saying the same thing which is confusing.
However, specifying not null for controlling access parameters provides
helpful documentation, and which parameters are controlling might
change, or might not be obvious, so this sort of specification should
be permitted, despite being redundant.
Modify 3.10(6/2) to
[null exclusion] access [constant] subtype_mark |
| [null exclusion] access [protected] procedure parameter_profile
| [null exclusion] access [protected] function parameter_and_result_profile
Add after 3.9.2(11):
If a dispatching operation is defined by a subprogram_renaming_declaration or a
generic_instantiation, any controlling access parameter or controlling result of
the subprogram shall be null excluding.
AARM Note on incompatibility:
This rule will require the addition of an explicit "not null" on
non-dispatching operations that are later renamed to be dispatching, or
on a generic that is used to define a dispatching operation.
The draft rationale says:
For uniformity, Ada 2005 permits all three forms with anonymous access types.
And we can also add not null so we can write all the following in Ada 2005
procedure P1(X: access T)
procedure P2(X: access constant T);
procedure P3(X: access all T);
procedure P4(X: not null access T);
procedure P5(X: not null access constant T);
procedure P6(X: not null access all T);
Note that two anomalies remain. One is that access T is deemed to be
short for access all T when it occurs in an anonymous access type in
order to permit compatibility between Ada 95 and Ada 2005. And so P1
and P3 are the same.
To have required all existing users to insert all in their access
parameters would have been too much of a burden. Similarly P4 and P6
are the same as well.
Moreover, as mentioned above, there is also the anomaly that controlling
parameters are still always null excluding and so in that case P1, P3,
P4, and P6 are all the same.
It is very confusing to have unnecessary ways of saying the same thing.
We are stuck with access T as a parameter as being general because of
backwards compatibility with Ada 95.
It is therefore proposed that anonymous access types should just take the
AV: access T;
AC: access constant T;
AV: access all T;
should not be permitted.
This makes them behave like normal object declarations where we either
have constant or nothing.
The anomaly is with named access types having to distinguish between
pool-specific and general access types. There is no reason why this should
be extended to anonymous access types.
Similarly, controlling access parameters have to be null excluding but
for compatibility with Ada 95 we cannot require the programmer to insert
not null everywhere. We considered disallowing an explicit not null
where they are implicit, but it was anticipated that after a transition
period, explicit not null would be used everywhere it applies, and disallowing
its use for controlling access parameters or results would defeat this.
For a dispatching operation defined by renaming or instantiation, we require
that the renamed subprogram or generic subprogram be null excluding for each
access parameter or access result that ends up controlling in the renaming or
the instance. For example:
type GT is private;
procedure Gen_Subp_1(Y : access GT);
type GT is private;
procedure Gen_Subp_2(Y : not null access GT);
with Gen_Subp_1; with Gen_Subp_2;
package P is
type T is tagged ....
package Inner is
procedure Not_Disp_1(X : access T);
procedure Not_Disp_2(X : not null access T);
procedure Ren1(X : access T) renames Not_Disp_1; --
procedure Ren2(X : access T) renames Not_Disp_2; --
procedure Inst1 is new Gen_Subp_1(T); --
procedure Inst2 is new Gen_Subp_2(T); --
Questions? Ask the ACAA Technical Agent