Version 1.1 of ai05s/ai05-0199-1.txt
!standard 4.3.1(16) 10-02-12 AI05-0199-1/01
!class binding interpretation 10-02-12
!status work item 10-02-12
!status received 09-08-14
!priority Low
!difficulty Easy
!qualifier Omission
!subject Record aggregates with components of anonymous access types
!summary
A record aggregate expression can be shared between components of
statically matching anonymous access types.
!question
Consider the following two record types:
type List_Element1 is record
Data : Integer;
Prev, Next : access List_Element1;
end record;
type List_Element2;
type List_Element2_Access is access all List_Element2;
type List_Element2 is record
Data : Integer;
Prev, Next : List_Element2_Access;
end record;
then:
Obj2 : List_Element2 := (Data => -1, Prev | Next => null);
is legal, while:
Obj1 : List_Element1 := (Data => -1, Prev | Next => null);
is illegal, as the types of Prev and Next are not the same, and thus
the expression "null" violated 4.3.1(16).
Should this be changed? (Yes.)
!recommendation
(See Summary.)
!wording
Modify 4.3.1(16):
If a record_component_association with an expression has two or more associated
components, all of them shall be of the same type{, or all of them shall be of
anonymous access types and the anonymous access types of the components
statically match}.
!discussion
For most purposes, all anonymous access types with the same designated type are
treated like the same type. For instance, values are implicitly converted
between them.
So it's weird that an expression like the one in the question is illegal.
Moreover, multiple components declared with a single component_declaration can
be initialized with a single default expression, so it would be unusual if they
couldn't appear together in an aggregate.
We require static matching of the anonymous access types so that the designated
subtypes and constantness of the types are the same -- otherwise the legality of
the expression could be different for the different components.
Note that using static matching goes slightly further than we need to; we don't
need the exclusions of the types or the constraints of the designated types to
be the same, but this is a permission that doesn't need to be very wide. The
main concern is multiple components from the same declaration can use a single
expression; anything beyond that is unnecessary.
We briefly considered replacing the entire rule by a requirement that the
component types statically match, but that is (slightly) incompatible --
components whose types are the same but whose constraints or exclusions are
different would not be allowed as they now are. This isn't worth any
incompatibility at all, so we opted for the longer wording.
--!corrigendum 3.9.3(4/2)
!ACATS Test
An ACATS C-Test should be created that is similar to the example in the
question.
!appendix
!topic Record aggregates when components have anonymous access types
!reference 4.3.1(16)
!from Adam Beneschan 09-08-14
!discussion
This is not an issue of burning importance, but I'd like to throw out a proposed
change to the last sentence of 4.3.1(16):
If a record_component_association with an expression has two or more associated
components, all of them shall be of the same type.
to something like:
If a record_component_association with an expression has two or more associated
components, all of them shall be of the same type, or all of them shall be of
anonymous access types, and the designated subtypes of the anonymous access
types shall statically match.
Currently, if you have a record like this:
type List_Element is record
Data : Integer;
Prev : access List_Element;
Next : access List_Element;
end record;
or, equivalently,
type List_Element is record
Data : Integer;
Prev, Next : access List_Element;
end record;
you can't specify an aggregate like this:
(Data => -1, Prev | Next => null);
although you *could* do so if the types of Prev and Next were the a named access
type.
****************************************************************
Questions? Ask the ACAA Technical Agent