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.
Name Resolution 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.
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:
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
, and each value of that subtype that
satisfies its predicate
shall be covered by some discrete_choice
[(either explicitly or by others
The exemption for a discriminated type declared
in an instance allows the following example:
type T is new Integer;
package G is
type Rec (Discrim : T) is record
case Discrim is
when -10 .. -1 =>
Foo : Float;
when others =>
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)].
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
Status : State;
case Unit is
when Printer =>
Line_Count : Integer range 1 .. Page_Size;
when others =>
Cylinder : Cylinder_Index;
Track : Track_Number;
Examples of record
subtype Drum_Unit is Peripheral(Drum);
subtype Disk_Unit is Peripheral(Disk);
Examples of constrained
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
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 clause on Array Types.
The rule requiring that the discriminant denote
a discriminant of the type being defined seems to have been left implicit
Incompatibilities With Ada 2005
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
Subtypes with static predicates
can be used in discrete_choices,
and the coverage rules are modified to respect the predicates.
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.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe