Version 1.23 of ais/ai-00231.txt
!standard 3.10 (06) 05-07-11 AI95-00231/16
!standard 3.2 (07)
!standard 3.2 (08)
!standard 3.2.2 (03)
!standard 3.4 (06)
!standard 3.7 (05)
!standard 3.7 (09)
!standard 3.10 (02)
!standard 3.10 (12)
!standard 3.10 (13)
!standard 3.10 (14/1)
!standard 3.10 (15)
!standard 4.2 (07)
!standard 4.5.2 (30)
!standard 4.6 (49)
!standard 4.6 (51)
!standard 4.9.1 (02)
!standard 6.1 (13)
!standard 6.1 (15)
!standard 6.1 (23)
!standard 6.1 (24)
!standard 6.4 (12)
!standard 7.4 (07)
!standard 8.5.1 (04)
!standard 8.6 (20)
!standard 8.6 (25)
!standard 11.5 (11/1)
!standard 12.5.1 (10)
!standard 12.5.4 (04)
!class amendment 00-04-13
!status Amendment 200Y 04-01-09
!status WG9 Approved 04-06-18
!status ARG Approved 10-0-1 03-12-13
!status work item 00-04-13
!status received 00-04-13
!priority Medium
!difficulty Hard
!subject Access-to-constant parameters and null-excluding access subtypes
!summary
Parameters and discriminants of an anonymous access-to-constant type are
introduced. Non-controlling access parameters and access discriminants
are changed to allow having a null value by default, but allow null to
be excluded explicitly. Null-excluding subtypes of a named access type
are introduced.
!problem
(See discussion.)
!proposal
Change non-controlling access parameters and access discriminants to
allow them to have null values. This represents a return to the original
Ada 83 model where all access types include a null value.
Allow the notion of a null-excluding access subtype, by introducing a
a "null exclusion" ("not null"), and allow it on subtype indications,
access type definitions, and access definitions. We don't call it a
"constraint" because doing so creates various wording issues relating to
"constrained" versus "unconstrained".
Generalize access_definition to allow specification of access-to-constant and
a null exclusion for anonymous access types.
!wording
Add to 3.2(7):
The set of possible values for an object of an access type can also be
subjected to a condition that excludes the null value (see 3.10).
Add to the penultimate sentence of 3.2(8):
...of the values of its type that satisfy its constraint {and any exclusion
of the null value}.
Replace paragraph 3.2.2(3) with:
subtype_indication ::=
[null_exclusion] subtype_mark [constraint]
Add after 3.4(6):
The first subtype of the derived type excludes null (see 3.10) if and
only if the parent subtype excludes null.
Modify 3.7(5) to:
discriminant_specification ::=
defining_identifier_list : [null_exclusion] subtype_mark [:= default_expression]
| defining_identifier_list : access_definition [:= default_expression]
Modify the first sentence of 3.7(9):
The subtype of a discriminant may be defined by {an optional null_exclusion
and} a subtype_mark, in which case the subtype_mark shall denote a discrete
or access subtype, .... is of an anonymous [general access-to-variable]
{access} type [whose designated subtype is denoted by the subtype_mark of
the access_definition].
Modify 3.10(2) to:
access_type_definition ::=
[null_exclusion] access_to_object_definition
| [null_exclusion] access_to_subprogram_definition
Modify 3.10(6) to:
null_exclusion ::= not null
access_definition ::=
[null_exclusion] access [general_access_modifier] subtype_mark
Modify 3.10(12) to:
An access_definition defines an anonymous general access type; the subtype
mark denotes its designated subtype. If the general_access_modifier
constant appears, the type is an access-to-constant type;
otherwise it is an
access-to-variable type. An access_definition is used
in the specification of an access discriminant (see 3.7) or an access
parameter (see 6.1). [NOTE: Drop this last sentence if AI-230 is approved.]
Modify 3.10(13) as follows:
For each [(named)] access type, there is [a literal null which has] a null
access value designating no entity at all{, which can be obtained by
converting the literal null to the access type}. The null value of
[a named] {an} access type is the ... in the case of [a named] {an}
access-to-object type, an allocator, which returns ...
Also, make the editorial correction of swapping "a non-intrinsic subprogram"
and "an aliased view of an object" in order to get the subprogram away from
the aliased view.
Add after 3.10(13):
A null_exclusion in a construct specifies that the null value does not
belong to the access subtype defined by the construct, that is, the access
subtype excludes null. In addition, the anonymous access subtype defined
by the access_definition for a controlling access parameter (see 3.9.2)
excludes null. Finally, for a subtype_indication without a null_exclusion,
the subtype denoted by the subtype_indication excludes null if and only if
the subtype denoted by the subtype_mark in the subtype_indication excludes
null.
AARM Note: Controlling access_definitions exclude null because it
is necessary to read the tag to dispatch, and null has no tag. We
would have preferred to require not null to be specified for such
parameters, but that would have been too incompatible with Ada 95.
Add after 3.10(14/1):
Legality Rules
If a subtype_indication, discriminant_specification,
parameter_specification, parameter_and_result_profile,
object_renaming_declaration, or formal_object_declaration has a
null_exclusion, the subtype_mark in that construct shall denote an access
subtype that does not exclude null.
Modify 3.10(15) as follows:
A composite_constraint is compatible with an unconstrained access subtype
if it is compatible with the designated subtype. {A null_exclusion is
compatible with any access subtype that does not exclude null.} An
access value satisfies a composite_constraint of an access subtype if it
equals the null value of its type or if it designates an object whose value
satisfies the constraint. {An access value satisfies an exclusion of
the null value if it does not equal the null value of its type.}
Delete paragraph 4.2(7) which says that anonymous access types don't
have a null value.
Replace 4.5.2(30) with:
The tested type is not scalar, and the value of the simple_expression
satisfies any constraints of the named subtype, and:
* if the type of the simple_expression is class-wide, the value has a tag
that identifies a type covered by the tested type;
* if the tested type is an access type and the named subtype excludes
null, the value of the simple_expression is not null.
Replace 4.6(49) with:
If the operand value is null, the result of the conversion is the null
value of the target type.
Add to the end of 4.6(51):
If the target subtype excludes null, then a check is
made that the value is not null.
Change 4.9.1(2):
A subtype statically matches another subtype of the same type if they have
statically matching constraints{, and, for access subtypes, either both or
neither exclude null}. Two anonymous access{-to-object} subtypes statically
match if their designated subtypes statically match{, and either both or
neither exclude null, and either both or neither are access-to-constant}.
Modify 6.1(13):
parameter_and_result_profile ::=
[formal_part] return [null_exclusion] subtype_mark
Modify 6.1(15):
parameter_specification ::=
defining_identifier_list : mode [null_exclusion] subtype_mark [:= default_expression]
| defining_identifier_list : access_definition [:= default_expression ]
Modify 6.1(23):
The nominal subtype of a formal parameter is the subtype [denoted]
{determined} by the {optional null_exclusion and the} subtype_mark, or
defined by the access_definition, in the parameter_specification.
{The nominal subtype of a function result is the subtype
determined by the optional null_exclusion and the subtype_mark in
the parameter_and_result_profile.}
Modify 6.1(24):
.... An access parameter is of an anonymous [general access-to-variable]
{access} type (see 3.10). ...
Replace 6.1(28) with:
For any result, the nominal subtype of the function result.
Modify 6.4(12):
...the nominal subtype of the constant is given by
the {nominal}[result] subtype of the function{ result}.
Add after 7.4(7):
* If the subtype of the deferred constant declaration excludes null, the
subtype of the full declaration shall also exclude null.
Add to the end of 8.5.1(4), if AI-230 is adopted:
In the case where the type is defined by an access_definition,
the renamed entity shall be of an access-to-constant type if and
only if the access_definition defines an access-to-constant type.
Modify 8.6(20):
.. universal [numeric] literals...
Modify 8.6(25):
* when T is an anonymous access{-to-object} type (see 3.10) with designated
type D, to an access-to-[variable]{object} type whose designated type is
D'Class or is covered by D{, and that is access-to-constant only if T is
access-to-constant}.
Replace 11.5(11/1) by:
When evaluating a dereference (explicit or implicit), check that the value
of the name is not null. When converting to a null-excluding subtype, check
that the converted value is not null.
Add after 12.5.1(10)
* If the ancestor subtype is an access subtype, the actual subtype shall
exclude null if and only if the ancestor subtype excludes null.
Add to the end of 12.5.4(4):
If and only if the formal subtype excludes null, the actual subtype shall
exclude null.
!example
type Non_Null_Ptr is not null access T;
procedure Show(X : Non_Null_Ptr);
-- X guaranteed to not be null
procedure Pass_By_Ref(Y : not null access constant Rec);
--
--
procedure Display(W : access Window; G : access constant Graph'Class);
--
--
!discussion
It is surprising that an access-to-constant parameter/discriminant is
not available. There are several circumstances where such a
parameter/discriminant would be appropriate:
As a controlling parameter of an operation that doesn't modify the
designated object.
As a way to force pass-by-reference when interfacing with a foreign
language, when the external operation does not update the designated
object,
As a way to provide read-only access via a discriminant.
The rule disallowing "null" for access parameters and access discriminants has
turned out to be confusing, and not what is wanted in all cases when
interfacing with a foreign language. Therefore, we propose to revert to the
Ada 83 model where all access types include a null value, and to define an
explicit way to exclude nulls from an access subtype. "Access T" and
"access constant T" will include nulls by default (when not a controlling
parameter), even though this does not preserve complete upward compatibility.
Note that the only incompatibility is for cases where null was passed, and
these would have been rejected at compile-time or have raised Constraint_Error.
It was felt it was better to have this upward incompatibility than to have the
default be null-excluding for "access T" but not null-excluding for "access
constant T". Note that there is no upward incompatibility for controlling
access parameters; they always have null-excluding subtypes. Any worrisome loss
of efficiency due to allowing null for non-controlling access parameters, or
access discriminants, can be reversed by using an explicit null_exclusion. (It
would be easy to create a tool that added needed null_exclusions to Ada 95
programs.)
The general ability to specify an access subtype that excludes null for both
named and anonymous access types can provide useful documentation and higher
efficiency. This is especially true for parameters, by allowing the nullness
check to be "pushed" to the caller, where it can be more likely removed.
What should be the default initialization of an object of a subtype that
excludes null? It seems clear that the default is still null, and the
initialization will raise Constraint_Error. Hence, objects of such a subtype
will require explicit initialization in order to be useful.
Note that the "all" in an access_definition is redundant, since
anonymous access types are always considered "general" access
types. However, it was felt more confusing to disallow use of "all"
for anonymous access types, even though it has no effect.
We chose to require matching of null exclusion in generics.
For formal derived types, static constraint matching was already
the case for access subtypes. For formal access types, we claim
that the paradigm of use for null-excluding access types differs
dramatically from null-including access types, and hence it is
not sensible to allow the formal and actual to differ on this
dimension. It also significantly simplifies generic sharing if
null exclusion is known statically.
Note that we do not allow a null exclusion to be applied to an
already null-excluding subtype. This is analogous to the restriction
against reconstraining non-scalar subtypes. Given that we require
matching of null exclusion in generics, it will always be known
statically whether a given subtype excludes null, so there seems
no reason to allow "confirming" null exclusions. Just as likely it
might represent a confusion on the part of the programmer, so disallowing
it might help detect such confusion.
We discussed situations where you might want a single generic
to be usable with both null including and null excluding actual
subtypes. However, if one has a generic whose formal includes null,
and one wants to reuse it with an access subtype that excludes null,
you can do the instantiation using a null-including subtype of
the same access type and accomplish the same level of reuse.
A major advantage of requiring the actual to include null if the formal does is
that the generic can still declare default-initialized local variables of the
access type, without bumping into the null exclusion. The instantiatior only
cares about null exclusion on values returned from the instance, and these
checks would still be performed as part of assigning a returned value to a
variable of a null-excluding subtype. Forcing the generic itself to operate
internally obeying null exclusion would make it that much harder to reuse the
generic. For example:
generic
with type Designated_Type is limited private;
with type Formal_Acc is access Designated_Type;
procedure Gen(Ptr : in out Formal_Acc);
procedure Gen(Ptr : in out Formal_Acc) is
Local : Formal_Acc; --
begin
Local := new Designated_Type;
if Ptr /= null then
Ptr := Local;
end if;
end Gen;
type Acc_With_Null is access T;
subtype Acc_Non_Null is non null Acc_With_Null;
procedure Instance is new Gen(Acc_With_Null);
--
Y : Acc_Non_Null := new T;
begin
Instance(Ptr => Y);
Inside Gen, "Ptr" and other objects of type "Formal_Acc" (e.g. "Local") can
take on null values. However, on return from the call, if the actual
associated with "Ptr" is of a null-excluding subtype, then the appropriate
check for null will be performed. The instantiator doesn't care if somewhere
inside "Gen" there are pointers that are temporarily null. (Note that this
works because parameters of an access type use pass-by-copy. This approach
would not work if access values were passed by reference.)
Note that the complementary requirement is also important, namely that if the
formal excludes null, then so should the actual. This allows the code inside
the generic to assume that any object or component that is of the formal type
is non-null, even if it is passed from outside the generic. Hence, we
require matching both ways, namely the actual may exclude null if
and only if the formal excludes null.
[Note: In the !corrigendum wording below, we assume that AI-230 is also
approved.]
!corrigendum 3.2(7)
Replace the paragraph:
The set of possible values for an object of a given type can be subjected to a
condition that is called a constraint (the case of a null
constraint that specifies no restriction is also included); the rules for
which values satisfy a given kind of constraint are given in 3.5 for
range_constraints, 3.6.1 for index_constraints, and 3.7.1 for
discriminant_constraints.
by:
The set of possible values for an object of a given type can be subjected to a
condition that is called a constraint (the case of a null
constraint that specifies no restriction is also included); the rules for
which values satisfy a given kind of constraint are given in 3.5 for
range_constraints, 3.6.1 for index_constraints, and 3.7.1 for
discriminant_constraints. The set of possible values for an object of an
access type can also be subjected to a condition that excludes the null
value (see 3.10).
!corrigendum 3.2(8)
Replace the paragraph:
A subtype of a given type is a combination of the type,
a constraint on values of the type, and certain
attributes specific to the subtype.
The given type is called the type of the subtype.
Similarly, the associated constraint is called the
constraint of the subtype. The set of values
of a subtype consists of the values of its type
that satisfy its constraint.
Such values belong to the subtype.
by:
A subtype of a given type is a combination of the type,
a constraint on values of the type, and certain
attributes specific to the subtype.
The given type is called the type of the subtype.
Similarly, the associated constraint is called the
constraint of the subtype. The set of values
of a subtype consists of the values of its type
that satisfy its constraint and any exclusion of the null value.
Such values belong to the subtype.
!corrigendum 3.2.2(3)
Replace the paragraph:
subtype_indication ::= subtype_mark [constraint]
by:
subtype_indication ::= [null_exclusion] subtype_mark [constraint]
!corrigendum 3.4(6)
Insert after the paragraph:
The first subtype of the derived type is unconstrained if a
known_discriminant_part is provided in the declaration of the derived type, or
if the parent subtype is unconstrained. Otherwise,
the constraint of the first subtype corresponds to that of the parent
subtype in the following sense: it is the same as that of the parent subtype
except that for a range constraint (implicit or explicit), the value of each
bound of its range is replaced by the corresponding value of the derived type.
the new paragraph:
The first subtype of the derived type excludes null (see 3.10) if and
only if the parent subtype excludes null.
!corrigendum 3.7(5)
Replace the paragraph:
discriminant_specification ::=
defining_identifier_list : subtype_mark [:= default_expression]
| defining_identifier_list : access_definition [:= default_expression]
by:
discriminant_specification ::=
defining_identifier_list : [null_exclusion] subtype_mark [:= default_expression]
| defining_identifier_list : access_definition [:= default_expression]
!corrigendum 3.7(9)
Replace the paragraph:
The subtype of a discriminant may be defined by a subtype_mark, in which
case the subtype_mark shall denote a discrete or access subtype, or it may
be defined by an access_definition (in which case the subtype_mark of
the access_definition may denote any kind of subtype). A discriminant that
is defined by an access_definition is called an access discriminant and is
of an anonymous general access-to-variable type whose designated subtype is
denoted by the subtype_mark of the access_definition.
by:
The subtype of a discriminant may be defined by an optional null_exclusion
and a subtype_mark, in which case the subtype_mark shall denote a
discrete or access subtype, or it may be defined by an access_definition
(in which case the subtype_mark of the access_definition may denote
any kind of subtype). A discriminant that is defined by an
access_definition is called an access discriminant and is of an
anonymous access type.
!corrigendum 3.10(2)
Replace the paragraph:
access_type_definition ::=
access_to_object_definition
| access_to_subprogram_definition
by:
access_type_definition ::=
[null_exclusion] access_to_object_definition
| [null_exclusion] access_to_subprogram_definition
!corrigendum 3.10(6)
Replace the paragraph:
access_definition ::= access subtype_mark
by:
null_exclusion ::= not null
access_definition ::=
[null_exclusion] access [general_access_modifier] subtype_mark
!corrigendum 3.10(12)
Replace the paragraph:
An access_definition defines an anonymous general access-to-variable type;
the subtype_mark denotes its designated subtype. An
access_definition is used in the specification of an access discriminant
(see 3.7) or an access parameter (see 6.1).
by:
An access_definition defines an anonymous general access type; the
subtype_mark denotes its designated subtype. If the
general_access_modifier
constant appears, the type is an access-to-constant type; otherwise it is
an access-to-variable type.
!corrigendum 3.10(13)
Replace the paragraph:
For each (named) access type, there is a literal null which has a null access
value designating no entity at all. The null value of a named access type is
the default initial value of the type. Other values of an access type are
obtained by evaluating an attribute_reference for the Access or
Unchecked_Access attribute of an aliased view of an object or non-intrinsic
subprogram, or, in the case of a named access-to-object type, an allocator,
which returns an access value designating a newly created object (see 3.10.2).
by:
For each access type, there is a null access value designating no entity at
all, which can be obtained by (implicitly) converting the literal null to
the access type. The null value of an access type is the default initial value
of the type. Non-null values of an access type are obtained by evaluating an
attribute_reference for the Access or Unchecked_Access attribute of a
non-intrinsic subprogram or an aliased view of an object, or, in the case of an
access-to-object type, an allocator, which returns an access value
designating a newly created object (see 3.10.2).
A null_exclusion in a construct specifies that the
null value does not belong to the access subtype defined by the construct, that
is, the access subtype excludes null. In addition, the anonymous access
subtype defined by the access_definition for a controlling access
parameter (see 3.9.2) excludes null.
Finally, for a subtype_indication without a null_exclusion,
the subtype denoted by the subtype_indication excludes null if and
only if the subtype denoted by the subtype_mark in the
subtype_indication excludes null.
!corrigendum 3.10(14/1)
Insert after the paragraph:
All subtypes of an access-to-subprogram type are constrained. The first subtype
of a type defined by an access_definition or an
access_to_object_definition is unconstrained if the designated subtype is
an unconstrained array or discriminated subtype; otherwise it is constrained.
the new paragraph:
Legality Rules
A null_exclusion is only allowed in a subtype_indication,
discriminant_specification, parameter_specification,
parameter_and_result_profile, object_renaming_declaration, or
formal_object_declaration if the subtype_mark in the construct
denotes an access subtype that does not exclude null.
If a subtype_indication, discriminant_specification,
parameter_specification, parameter_and_result_profile,
object_renaming_declaration, or formal_object_declaration has a
null_exclusion, the subtype_mark in that construct shall denote
an access subtype that does not exclude null.
!corrigendum 3.10(15)
Replace the paragraph:
A composite_constraint is compatible with an unconstrained access
subtype if it is compatible with the designated subtype. An access value
satisfies a composite_constraint of an access subtype if it equals the
null value of its type or if it designates an object whose value satisfies the
constraint.
by:
A composite_constraint is compatible with an unconstrained access
subtype if it is compatible with the designated subtype. A null_exclusion
is compatible with any access subtype that does not exclude null. An
access value satisfies a composite_constraint of an access subtype if
it equals the null value of its type or if it designates an object whose value
satisfies the constraint. An access value satisfies an exclusion of the null
value if it does not equal the null value of its type.
!corrigendum 4.2(7)
Delete the paragraph:
A literal null shall not be of an anonymous access type, since such types
do not have a null value (see 3.10).
!corrigendum 4.5.2(30)
Replace the paragraph:
- The tested type is not scalar, and
the value of the simple_expression satisfies any constraints
of the named subtype, and, if the type of the simple_expression
is class-wide, the value has a tag that identifies a type covered by
the tested type.
by:
- The tested type is not scalar, and
the value of the simple_expression satisfies any constraints
of the named subtype, and:
- if the type of the simple_expression is class-wide, the
value has a tag that identifies a type covered by the tested type;
- if the tested type is an access type and the named subtype excludes
null, the value of the simple_expression is not null.
!corrigendum 4.6(49)
Replace the paragraph:
- If the target type is an anonymous access type, a check is made that
the value of the operand is not null; if the target is not an anonymous access
type, then the result is null if the operand value is null.
by:
- If the operand value is null, the result of the conversion is the null
value of the target type.
!corrigendum 4.6(51)
Replace the paragraph:
After conversion of the value to the target type, if the target subtype is
constrained, a check is performed that the value satisfies this constraint.
by:
After conversion of the value to the target type, if the target subtype is
constrained, a check is performed that the value satisfies this constraint.
If the target subtype excludes null, then a check is
made that the value is not null.
!corrigendum 4.9.1(2)
Replace the paragraph:
A subtype statically matches another subtype of the same type if they have
statically matching constraints. Two anonymous access subtypes statically match
if their designated subtypes statically match.
by:
A subtype statically matches another subtype of the same type if they have
statically matching constraints, and, for access subtypes, either both or
neither exclude null. Two anonymous access-to-object subtypes statically match
if their designated subtypes statically match, and either both or neither
exclude null, and either both or neither are access-to-constant.
!corrigendum 6.1(13)
Replace the paragraph:
parameter_and_result_profile ::= [formal_part] return subtype_mark
by:
parameter_and_result_profile ::=
[formal_part] return [null_exclusion] subtype_mark
!corrigendum 6.1(15)
Replace the paragraph:
parameter_specification ::=
defining_identifier_list : mode subtype_mark [:= default_expression]
| defining_identifier_list : access_definition [:= default_expression]
by:
parameter_specification ::=
defining_identifier_list : mode [null_exclusion] subtype_mark [:= default_expression]
| defining_identifier_list : access_definition [:= default_expression]
!corrigendum 6.1(23)
Replace the paragraph:
The nominal subtype of a formal parameter is the subtype denoted by the
subtype_mark, or defined by the access_definition, in the
parameter_specification.
by:
The nominal subtype of a formal parameter is the subtype determined
by the optional null_exclusion and the subtype_mark, or
defined by the access_definition, in the parameter_specification.
The nominal subtype of a function result is the subtype
determined by the optional null_exclusion and the subtype_mark in
the parameter_and_result_profile.
!corrigendum 6.1(24)
Replace the paragraph:
An access parameter is a formal in parameter specified by an
access_definition. An access parameter is of an anonymous general
access-to-variable type (see 3.10). Access parameters allow dispatching calls
to be controlled by access values.
by:
An access parameter is a formal in parameter specified by an
access_definition. An access parameter is of an anonymous access type (see
3.10). Access parameters allow dispatching calls to be controlled by access
values.
!corrigendum 6.1(28)
Replace the paragraph:
- For any result, the result subtype.
by:
- For any result, the nominal subtype of the function result.
!corrigendum 6.4(12)
Replace the paragraph:
A function_call denotes a constant, as defined in 6.5; the nominal subtype
of the constant is given by the result subtype of the function.
by:
A function_call denotes a constant, as defined in 6.5; the nominal subtype
of the constant is given by the nominal subtype of the function result.
!corrigendum 7.4(7)
Replace the paragraph:
- If deferred constant declaration includes the reserved word
aliased, then the full declaration shall also.
by:
- If deferred constant declaration includes the reserved word
aliased, then the full declaration shall also;
- If the subtype of the deferred constant declaration excludes null, the
subtype of the full declaration shall also exclude null.
!corrigendum 8.5.1(4)
Replace the paragraph:
The renamed entity shall be an object.
by:
The renamed entity shall be an object.
In the case where the type is defined by an access_definition,
the renamed entity shall be of an access-to-constant type if and
only if the access_definition defines an access-to-constant type.
!corrigendum 8.6(20)
Replace the paragraph:
The expected type for a given expression, name,
or other construct determines, according to the type resolution
rules given below, the types considered for the construct during
overload resolution.
The type resolution rules provide support for class-wide programming,
universal numeric literals, dispatching
operations, and anonymous access types:
by:
The expected type for a given expression, name,
or other construct determines, according to the type resolution
rules given below, the types considered for the construct during
overload resolution.
The type resolution rules provide support for class-wide programming,
universal literals, dispatching operations, and anonymous access types:
!corrigendum 8.6(25)
Replace the paragraph:
- when T is an anonymous access type (see 3.10) with designated
type D, to an access-to-variable type whose designated type is D'Class
or is covered by D.
by:
- when T is an anonymous access-to-object type (see 3.10) with
designated type D, to an access-to-object type whose designated type is
D'Class or is covered by D, and that is access-to-constant only if
T is access-to-constant.
!corrigendum 11.5(11/1)
Replace the paragraph:
When evaluating a dereference (explicit or implicit), check that the value of
the name is not null. When passing an actual parameter to a formal
access parameter, check that the value of the actual parameter is not null.
When evaluating a discriminant_association for an access discriminant,
check that the value of the discriminant is not null.
by:
When evaluating a dereference (explicit or implicit), check that the value of
the name is not null. When converting to a subtype that excludes
null, check that the converted value is not null.
!corrigendum 12.5.1(10)
Insert after the paragraph:
- If the ancestor subtype is an unconstrained discriminated subtype,
then the actual shall have the same number of discriminants, and each
discriminant of the actual shall correspond to a discriminant of the ancestor,
in the sense of 3.7.
the new paragraph:
- If the ancestor subtype is an access subtype, the actual subtype shall
exclude null if and only if the ancestor subtype excludes null.
!corrigendum 12.5.4(4)
Replace the paragraph:
If and only if the general_access_modifier constant applies to the
formal, the actual shall be an access-to-constant type. If the
general_access_modifier all applies to the formal, then the actual
shall be a general access-to-variable type (see 3.10).
by:
If and only if the general_access_modifier constant applies to the
formal, the actual shall be an access-to-constant type. If the
general_access_modifier all applies to the formal, then the actual
shall be a general access-to-variable type (see 3.10). If and only if the
formal subtype excludes null, the actual subtype shall exclude null.
!ACATS test
Tests should be created to check on the implementation of this feature.
!appendix
Randy Brukardt 00-04-13
This proposal was split out of the "with type" proposal (AI-00217) in
April 2000. Some early conversation on this feature can be found in that
AI's appendix.
*************************************************************
!topic Missing change in AI95-00231
!reference AI95-00231, RM95 6.1(24)
!from Adam Beneschan 09-30-02
!discussion
Nitpick du jour:
I just noticed AI95-00231, which proposes that, among other things,
ACCESS CONSTANT be allowed as a subprogram access parameter. It
appears that in the list of RM changes for this AI, 6.1(24) was
missed. This paragraph includes the sentence:
"An access parameter is of an anonymous general access-to-variable
type (see 3.10)."
which will no longer be true since the access parameter could now be
an access-to-constant type.
*************************************************************
From: Dan Eilers
Sent: Friday, January 17, 2003 2:41 PM
AI-231 proposes the syntax:
not_null_constraint ::= NOT NULL
for null-excluding subtypes of a named access type.
I propose generalizing this to allow value-excluding subtypes
of other named types, serving the same purpose:
> The general ability to specify an access subtype that excludes null for both
> named and anonymous access types can provide useful documentation and higher
> efficiency. This is especially true for parameters, by allowing the nullness
> check to be "pushed" to the caller, where it can be more likely removed.
The same principle applies to the division-by-zero check.
not_constraint ::= NOT NULL
not_constraint ::= NOT 0
not_constraint ::= NOT 0.0
not_constraint ::= NOT Friday
*************************************************************
From: Robert Dewar
Sent: Sunday, January 19, 2003 8:42 AM
While I am a little sympathetic to the non-null access type proposal, I
find Dan's proposal for extending it definitely inappropriate. It sounds
like a lot of extra work to specify and implement.
*************************************************************
From: Tucker Taft
Sent: Tuesday, May 6, 2003 2:49 PM
During the AdaUK Ada 200Y workshop, Franco Gasperoni made a good
suggestion. He felt it will be too confusing to make "access T" mean "access
all T not null" (I think others have made this point as well).
Why not just change the semantics of "access T" to allow null (though
when used as a controlling operand, there will be a run-time
check for non-null), so that "access all T" and "access T" are
synonyms. This will be upward compatible for programs that
don't raise Constraint_Error, and the slight potential
performance degradation when the non-null aspect of access T was
important can be made up for by using "not null" explicitly.
This seems like a reasonable suggestion, and is probably one
we have debated in the past, and just were perhaps worried
about the compatibility issue. But in fact, I suspect this
is the kind of thing that may fix more bugs that it creates.
Most uses of anon access types are for controlling operands,
and those will see no change. The other uses often discover
a need to pass "null" eventually, and then have to switch
to a named access type, or play some other game.
Certainly when interfacing with C or Java, an "access T" that allows
null will be more useful. And altough we could say that
"access T" is just a convenient shorthand for "access all T not null"
it does seem like a recipe for confusion when teaching Ada 200Y.
It seems like if the non-null aspect of an access parameter is
important, users will welcome the chance to say "not null" explicitly.
*************************************************************
From: John Barnes
Sent: Thursday, May 8, 2003 1:28 AM
Good idea.. I always hated the potential confusion as it was.
*************************************************************
From: Gary Dismukes
Sent: Tuesday, May 13, 2003 6:33 AM
I agree that this seems like a sensible change with minimal disadvantages.
*************************************************************
From: Robert A Duff
Sent: Thursday, May 8, 2003 7:34 AM
Me, three.
*************************************************************
From: Randy Brukardt
Sent: Saturday, September 27, 2003 6:15 PM
In the appendix of AI-231, I see a note from Adam Beneschan that 6.1(24) will
need to be changed (because it says "access-to-variable"). I think the AI needs
to include that, right?
*************************************************************
From: Randy Brukardt
Sent: Saturday, September 27, 2003 6:17 PM
3.7(9) has the same wording, and will need a similar fix.
*************************************************************
From: Tucker Taft
Sent: Sunday, September 28, 2003 9:09 AM
Good point. Can you make those fixes, or do
you want another version from me?
*************************************************************
From: Randy Brukardt
Sent: Monday, September 29, 2003 6:02 PM
The wording change isn't instantly obvious, so I think I'd prefer a new
version from you.
*************************************************************
From: Javier Miranda
Sent: Wednesday, January 7, 2004 12:29 PM
In file AI-00231.TXT (date 03-10-22) it is said:
access_definition ::=
[null_exclussion] ACCESS general_access_modifier subtype_mark
However, in AI-00254 (date 03-11-11) it is said:
access_definition ::=
[null_exclussion] ACCESS [general_access_modifier] subtype_mark |
...
It seems to me that this second alternative is the right one (to be
compatible with Ada95). In addition both proposals should have the same
rule. Is this a bug in AI-00231?
*************************************************************
From: Gary Dismukes
Sent: Wednesday, January 7, 2004 1:00 PM
This looks like a bug in AI-00231. Certainly there's no intent
to create an incompatibility by requiring an explicit modifier.
*************************************************************
From: Randy Brukardt
Sent: Wednesday, January 7, 2004 10:26 PM
The version that Tucker handed out at the meeting (AI-00231/07) doesn't have
this problem. I didn't post it in the hopes of saving redundant effort, but
it is now available in the version control system (only - not in the .ZIP
files).
*************************************************************
From: Javier Miranda
Sent: Thursday, January 8, 2004 3:33 AM
Thanks Randy. In the future I will use the versions
available in the version control system to avoid generating
unnecessary noise!
*************************************************************
From: Randy Brukardt
Sent: Thursday, January 8, 2004 11:55 AM
That's always preferrable, but it wouldn't have helped in this case, because
I didn't actually send the changes up until I saw your note. So only people
who were at the meeting had the new version.
*************************************************************
Questions? Ask the ACAA Technical Agent