Version 1.2 of ai05s/ai05-0199-1.txt
!standard 4.3.1(16) 10-11-22 AI05-0199-1/02
!class binding interpretation 10-02-12
!status Amendment 2012 10-11-22
!status ARG Approved 7-0-0 10-10-31
!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/2):
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 whose subtypes 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
types and constantness of the types are the same -- otherwise the legality of
the expression could be different for the different components. This does not
happen in any existing aggregates that pass 4.3.1(16/2).
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 that multiple components from the same declaration can use a
single expression; anything beyond that is unnecessary.
We considered making this rules similar to type conformance, saying something
like: "or all of them shall be of anonymous access types and whose designated
types are the same, or whose designated profiles are type conformant." But
that does not make the legality of the expressions the same. We could try to
add wording to make that the case, "and neither or both are access-to-constant",
but that just makes the wording really long and doesn't allow much in addition.
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 4.3.1(16/2)
Replace the paragraph:
Each record_component_association other than an others choice with
a <> shall have at least one associated component, and each needed component
shall be associated with exactly one record_component_association. If a
record_component_association with an expression has two or more
associated components, all of them shall be of the same type.
by:
Each record_component_association other than an others choice with
a <> shall have at least one associated component, and each needed component
shall be associated with exactly one record_component_association. 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 whose subtypes statically match.
!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.
****************************************************************
From: Randy Brukardt
Sent: Tuesday, November 23, 2010 12:14 AM
When we talked about the wording for the last AI (Record aggregates with
components of anonymous access types), Bob complained that the new wording
talked about subtypes where the old wording did not (for 4.3.1(16)).
Tucker then followed up by making the claim that this wording is only about name
resolution, and thus suggested that the wording be based on type conformance.
However, we ought to have read the !discussion that I had previously written for
this AI. I had written that I had chosen this wording not because it was similar
to the existing wording, but in order that the name resolution AND legality of
the expression is the same (not just the name resolution).
With the newly proposed wording:
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 for which the designated types are the same, or the
designated profiles are type conformant}.
It is trivial to come up with expressions that legal for some but not all of the
components. (Which means the expression has to be checked for legality
repeatedly.) For instance:
type Rec_1 is record
A : access Integer;
B : access constant Integer;
end record;
I_ObJ : aliased Integer;
R1_Obj : Rec_1 := (others => I_Obj'access);
This passes the rule given for 4.3.1(16/3) (designated types are the same), the
expression resolves properly, the expression is legal for component A, but the
expression is not legal for component B.
I think it would only be OK to have this property of having to recheck the
legality of these expressions for each component if it in fact already exists
for some set of components and an aggregate expression that passes the current
version of 4.3.1(16). However, I cannot think of any such expression in quite a
bit of trying. I thought I had a case for array components:
type Rec_2 is record
A : String(1..2);
B : String(1..3);
end record;
R2_Obj : Rec_2 := (others => "123");
Since there are too many elements for component A. But this is a dynamic check;
the aggregate is legal but raises Constraint_Error at runtime. This is
definitely not the same case.
And the same has occurred for every other case that I've come up with (or it
violated the original 4.3.1(16)).
As such, I don't think we want to use the rule that we came up with in Fairfax.
I'd prefer to revert to the wording we had before Bob complained:
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 their subtypes statically match}.
For the record, here is the important part of my original !discussion:
We require static matching of the anonymous access types so that the designated
types 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.
Thoughts??
****************************************************************
Questions? Ask the ACAA Technical Agent