3.8.1 Variant Parts and Discrete Choices
Language Design Principles
The definition of “cover” in this
subclause and the rules about discrete choices are designed so that they
are also appropriate for array aggregates and case statements.
The rules of this subclause intentionally parallel
those for case statements.
Syntax
Name Resolution Rules
Legality Rules
The discriminant of the
variant_part
shall be of a discrete type.
Ramification: It shall not be of an access
type, named or anonymous.
Ramification: For
case_statements,
this includes values outside the range of the static subtype (if any)
to be covered by the choices. It even includes values outside the base
range of the case expression's type, since values of numeric types (and
undefined values of any scalar type?) can be outside their base range.
The possible values
of the discriminant of a
variant_part
shall be covered as follows:
{
AI05-0153-3}
{
AI05-0188-1}
{
AI05-0262-1}
{
AI12-0071-1}
If the discriminant is of a static constrained scalar subtype then, except
within an instance of a generic unit, each non-
others discrete_choice
shall cover only values in that subtype that satisfy its predicates,
and each value of that subtype that satisfies its predicates shall be
covered by some
discrete_choice
[(either explicitly or by
others)];
Reason: {
AI05-0188-1}
The exemption for a discriminated type declared in an instance allows
the following example:
generic
type T is new Integer;
package G is
type Rec (Discrim : T) is record
case Discrim is
when -10 .. -1 =>
Foo : Float;
when others =>
null;
end case;
end record;
end G;
package I is new G (Natural); -- Legal
Reason: The base range is not known statically
in this case.
Otherwise, each value of the base range of the
type of the discriminant shall be covered [(either explicitly or by others)].
Static Semantics
Dynamic Semantics
Implementation Note: This is not a “check”;
it cannot be suppressed. However, in most cases it is not necessary to
generate any code to raise this exception. A test is needed (and can
fail) in the case where the discriminant subtype has a Static_Predicate
specified, it also has predicate checking disabled, and the discriminant
governs a
variant_part
which lacks a
when others choice.
The test also could fail for a static discriminant
subtype with range checking suppressed and the discriminant governs a
variant_part
which lacks a
when others choice. But execution is erroneous if
a range check that would have failed is suppressed (see
11.5),
so an implementation does not have to generate code to check this case.
(An unchecked failed predicate does not cause erroneous execution, so
the test is required in that case.)
Like the checks associated with a per-object
constraint, this test is not made during the elaboration of a
subtype_indication.
Examples
Example of record
type with a variant part:
type Device is (Printer, Disk, Drum);
type State is (Open, Closed);
type Peripheral(Unit : Device := Disk) is
record
Status : State;
case Unit is
when Printer =>
Line_Count : Integer range 1 .. Page_Size;
when others =>
Cylinder : Cylinder_Index;
Track : Track_Number;
end case;
end record;
Examples of record
subtypes:
subtype Drum_Unit is Peripheral(Drum);
subtype Disk_Unit is Peripheral(Disk);
Examples of constrained
record variables:
Writer : Peripheral(Unit => Printer);
Archive : Disk_Unit;
Extensions to Ada 83
In Ada 83, the discriminant
of a
variant_part
is not allowed to be of a generic formal type. This restriction is removed
in Ada 95; an
others discrete_choice
is required in this case.
Wording Changes from Ada 83
{
AI05-0299-1}
We have added the term Discrete Choice to the title since this is where
they are talked about. This is analogous to the name of the subclause
"Index Constraints and Discrete Ranges" in the subclause on
Array Types.
The rule requiring that the discriminant denote
a discriminant of the type being defined seems to have been left implicit
in RM83.
Incompatibilities With Ada 2005
{
AI05-0158-1}
Membership tests are no longer allowed as a
discrete_choice,
in order that those tests can be expanded to allow multiple tests in
a single expression without ambiguity. Since a membership test has a
boolean type, they are very unlikely to be used as a
discrete_choice.
Extensions to Ada 2005
{
AI05-0153-3}
Subtypes with static predicates can be used in
discrete_choices,
and the coverage rules are modified to respect the predicates.
{
AI05-0188-1}
Variants in generic specifications are no longer rejected if the subtype
of the actual type does not include all of the case choices. This probably
isn't useful, but it is consistent with the treatment of
case_expressions.
Wording Changes from Ada 2005
{
AI05-0290-1}
Added a test that some
variant
covers the value of a discriminant that governs a
variant_part.
This is similar to the test that some case limb covers the value of the
Selecting_expression
of a
case_statement.
This test cannot change the behavior of any nonerroneous Ada 2005 program,
so it is not an inconsistency.
Wording Changes from Ada 2012
{
AI12-0071-1}
Corrigendum: Updated wording of the coverage rules to use the
new term "satisfies the predicates" (see
3.2.4).
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe