Overview of Ada 2022
7.12 Objects, Values, Conversions and Renaming
There are several AIs that aim to make Ada more consistent
in its treatment of type conversions and qualified expressions, objects
and values.
In Ada 2012 a type
conversion between two tagged types (termed a view conversion) gives
an object, which can be renamed, whereas a type conversion between two
untagged types (termed a value conversion) gives a value, which cannot.
In Ada 2022 a value conversion of an object is added to the list of things
deemed to be an object, making it consistent with a qualified expression.
If we have
Max : constant Natural := 10;
then the following
are now all legal:
Ren1 : Natural renames Max; -- Legal
Ren2 : Natural renames Natural'(Max); -- Qualified expression, legal
Ren3 : Natural renames Natural(Max); -- Value conversion, was illegal, now legal
Renaming values (AI12-0383).
takes this further by allowing values to be renamed anyway, besides objects.
Make subtype_mark optional in object renames (AI12-0275).
This makes the subtype optional in object renaming
declarations (see RM
8.5.1).
The expression will be correctly typed as long as the right hand object
can be resolved to only one specific type.
It has long been an
irritant that writing a renaming declaration required looking up the
subtype of the object, and giving the subtype can be misleading anyway.
The reader may be surprised to find that the following is valid Ada:
subtype My_Subtype is Integer range 3 .. 5;
subtype Garbage_Subtype is Integer range -19 .. -7;
X : My_Subtype;
Y : Garbage_Subtype renames X;
begin
case Y is
when 3 .. 5 =>
pragma Assert (Y in 3 .. 5);
end case;
The subtype given in the renaming merely has to be
a subtype of the same type as the object being renamed. The constraints,
null exclusions, and predicates of the subtype given in the renaming
are ignored; instead they are taken from the subtype of the object being
renamed. Note that the case statement has to have alternatives for each
possible value of the subtype of X, not of
the supposed subtype of Y.
Requiring the subtypes to match has been considered
in the past, but backward compatibility concerns have always prevented
this. For backward compatibility reasons the subtype may still be given,
but it is (usually) no longer required.
Renaming of a qualified expression of a variable
(AI12-0401).
Ada 2012 allows a qualified
expression to be renamed (though possibly this had not been implemented
by anyone until recently). In the following, three subtypes are involved:
subtype Subtype_1 is Integer range ...;
subtype Subtype_2 is Integer range ...;
subtype Subtype_3 is Integer range ...;
X : Subtype_1;
Y : Subtype_2 renames Subtype_3'(X);
As described under
Make subtype_mark optional
in object renames (AI12-0275),
Subtype_2 is largely irrelevant. Typically,
a qualified expression is used to confirm which type is meant when there
is a possible ambiguity, as in:
type Traffic_Light is (Red, Amber, Green);
type Gemstones is (Amber, Ruby, Topaz);
... Traffic_Lights'(Amber) ...
... Gemstones'(Amber) ...
But in the above it
is not a case of X being renamed, and Subtype_3'
just being there to confirm the type; instead it is the whole qualified
expression Subtype_3'(X) that is the object
being renamed. Thus Y takes its constraints,
null exclusions, and predicates from Subtype_3.
This could be problematic if Subtype_3 has
a narrower range than Subtype_1, as in the
following:
X : Natural := ...;
Y : Positive renames Positive'(X); -- Legal in Ada 2012, illegal in Ada 2022
begin
X := 0; -- Alert!!
case Y is
when 1 .. Positive'Last =>
pragma Assert (Y > 0);
end case;
X is set to a value outside
of the range of Y, effectively bypassing the
range check at the time of renaming, which is meant to be a one-off affair,
and not have to be repeated at each subsequent use of Y.
To fix this hole,
Renaming of a qualified expression
of a variable (AI12-0401)
requires
Subtype_3 to match either
Subtype_1
or its base type (in this case,
Integer).
Note that the converse problem of writing a value to
Y
outside of the range of
X does not arise as
a qualified expression gives a constant (i.e. read-only) view.
© 2021, 2022 Jeff Cousins