Contents Index Search Previous Next
5.4 Case Statements
1
[A case_statement
selects for execution one of a number of alternative sequences_of_statements;
the chosen alternative is defined by the value of an expression.]
Syntax
2
case_statement
::=
case expression is
case_statement_alternative
{
case_statement_alternative}
end case;
3
case_statement_alternative
::=
when discrete_choice_list =>
sequence_of_statements
Name Resolution Rules
4
{expected type (case expression)
[partial]} The
expression
is expected to be of any discrete type.
{expected
type (case_statement_alternative discrete_choice) [partial]}
The expected type for each
discrete_choice
is the type of the
expression.
Legality Rules
5
The expressions
and discrete_ranges given as discrete_choices
of a case_statement shall be static.
[A discrete_choice others,
if present, shall appear alone and in the last discrete_choice_list.]
6
The possible values of the expression
shall be covered as follows:
7
- If the expression
is a name [(including a type_conversion
or a function_call)] having a static
and constrained nominal subtype, or is a qualified_expression
whose subtype_mark denotes a static
and constrained scalar subtype, then each non-others discrete_choice
shall cover only values in that subtype, and each value of that subtype
shall be covered by some discrete_choice
[(either explicitly or by others)].
7.a
Ramification: Although
not official names of objects, a
value conversion still has a defined nominal subtype, namely its target
subtype. See 4.6.
8
- If the type of the expression
is root_integer, universal_integer, or a descendant of
a formal scalar type, then the case_statement
shall have an others discrete_choice.
8.a
Reason: This is because
the base range is implementation defined for root_integer and
universal_integer, and not known statically in the case of a formal
scalar type.
9
- Otherwise, each value of the base
range of the type of the expression
shall be covered [(either explicitly or by others)].
10
Two distinct discrete_choices
of a case_statement shall not cover
the same value.
10.a
Ramification: The goal
of these coverage rules is that any possible value of the expression
of a case_statement should be covered
by exactly one discrete_choice of
the case_statement, and that this
should be checked at compile time. The goal is achieved in most cases,
but there are two minor loopholes:
10.b
- If the expression
reads an object with an invalid representation (e.g. an uninitialized
object), then the value can be outside the covered range. This can happen
for static constrained subtypes, as well as nonstatic or unconstrained
subtypes. It cannot, however, happen if the case_statement
has the discrete_choice others,
because others covers all values, even those outside the subtype.
10.c
- If the compiler
chooses to represent the value of an expression of an unconstrained subtype
in a way that includes values outside the bounds of the subtype, then
those values can be outside the covered range. For example, if X: Integer
:= Integer'Last;, and the case expression
is X+1, then the implementation might choose to produce the correct value,
which is outside the bounds of Integer. (It might raise Constraint_Error
instead.) This case can only happen for non-generic subtypes that are
either unconstrained or non-static (or both). It can only happen if there
is no others discrete_choice.
10.d
In the uninitialized variable
case, the value might be anything; hence, any alternative can be chosen,
or Constraint_Error can be raised. (We intend to prevent, however, jumping
to random memory locations and the like.) In the out-of-range case, the
behavior is more sensible: if there is an others, then the implementation
may choose to raise Constraint_Error on the evaluation of the expression
(as usual), or it may choose to correctly evaluate the expression
and therefore choose the others alternative. Otherwise (no others),
Constraint_Error is raised either way -- on the expression
evaluation, or for the case_statement
itself.
10.e
For an enumeration type with
a discontiguous set of internal codes (see 13.4),
the only way to get values in between the proper values is via an object
with an invalid representation; there is no ``out-of-range'' situation
that can produce them.
Dynamic Semantics
11
{execution (case_statement)
[partial]} For the execution of a
case_statement
the
expression is first evaluated.
12
If the value of the expression
is covered by the discrete_choice_list
of some case_statement_alternative,
then the sequence_of_statements
of the _alternative is executed.
13
{Overflow_Check [partial]}
{check, language-defined (Overflow_Check)}
{Constraint_Error (raised by failure
of run-time check)} Otherwise (the value
is not covered by any
discrete_choice_list,
perhaps due to being outside the base range), Constraint_Error is raised.
13.a
Ramification: In this
case, the value is outside the base range of its type, or is an invalid
representation.
14
5 The execution of a case_statement
chooses one and only one alternative. Qualification of the expression
of a case_statement by a static
subtype can often be used to limit the number of choices that need be
given explicitly.
Examples
15
Examples of
case statements:
16
case Sensor is
when Elevation => Record_Elevation(Sensor_Value);
when Azimuth => Record_Azimuth (Sensor_Value);
when Distance => Record_Distance (Sensor_Value);
when others => null;
end case;
17
case Today is
when Mon => Compute_Initial_Balance;
when Fri => Compute_Closing_Balance;
when Tue .. Thu => Generate_Report(Today);
when Sat .. Sun => null;
end case;
18
case Bin_Number(Count) is
when 1 => Update_Bin(1);
when 2 => Update_Bin(2);
when 3 | 4 =>
Empty_Bin(1);
Empty_Bin(2);
when others => raise Error;
end case;
Incompatibilities With Ada 83
18.a.1/1
{incompatibilities with
Ada 83} In Ada 95, function_calls
and type_conversions are names,
whereas in Ada 83, they were expressions.
Therefore, if the expression of
a case_statement is a function_call
or type_conversion, and the result
subtype is static, it is illegal to specify a choice outside the bounds
of the subtype. For this case in Ada 83 choices only are required to
be in the base range of the type.
18.a.2/1
In addition, the rule about
which choices must be covered is unchanged in Ada 95. Therefore, for
a case_statement whose expression
is a function_call or type_conversion,
Ada 83 required covering all choices in the base range, while Ada 95
only requires covering choices in the bounds of the subtype. If the case_statement
does not include an others discrete_choice,
then a legal Ada 83 case_statement
will be illegal in Ada 95 if the bounds of the subtype are different
than the bounds of the base type.
Extensions to Ada 83
18.a
{extensions to Ada 83}
In Ada 83, the expression
in a case_statement is not allowed
to be of a generic formal type. This restriction is removed in Ada 95;
an others discrete_choice
is required instead.
18.b
In Ada 95, a function call is
the name of an object; this was not true in Ada 83 (see 4.1,
``Names''). This change makes the following
case_statement legal:
18.c
subtype S is Integer range 1..2;
function F return S;
case F is
when 1 => ...;
when 2 => ...;
-- No others needed.
end case;
18.d
Note that the result subtype
given in a function renaming_declaration
is ignored; for a case_statement
whose expression calls a such a function, the full coverage rules are
checked using the result subtype of the original function. Note that
predefined operators such as "+" have an unconstrained result
subtype (see 4.5.1). Note that generic formal
functions do not have static result subtypes. Note that the result subtype
of an inherited subprogram need not correspond to any namable subtype;
there is still a perfectly good result subtype, though.
Wording Changes from Ada 83
18.e
Ada 83 forgot to say what happens
for ``legally'' out-of-bounds values.
18.f
18.g
In the Name Resolution Rule
for the case expression, we no longer need RM83-5.4(3)'s ``which must
be determinable independently of the context in which the expression
occurs, but using the fact that the expression must be of a discrete
type,'' because the expression is
now a complete context. See 8.6, ``The
Context of Overload Resolution''.
18.h
Since type_conversions
are now defined as names, their
coverage rule is now covered under the general rule for names,
rather than being separated out along with qualified_expressions.
Contents Index Search Previous Next Legal