5.4 Case Statements
This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue
[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/3case_statement
::=
case selecting_expression
is
case_statement_alternative
{case_statement_alternative
}
end case;
3case_statement_alternative
::=
when discrete_choice_list
=>
sequence_of_statements
Name Resolution Rules
4/3The selecting_expression
is expected to be of any discrete type. The expected type for each discrete_choice
is the type of the selecting_expression
.
Legality Rules
5/3The choice_expression
s, subtype_indication
s, and range
s given as discrete_choice
s of a case_statement
shall be static. [A discrete_choice
others, if present, shall appear alone and in the last discrete_choice_list
.]
The possible values of the selecting_expression
shall be covered (see 3.8.1) as follows:
- If the selecting_
expression
is aname
[(including atype_conversion
,qualified_expression
, orfunction_call
)] having a static and constrained nominal subtype, then each non-othersdiscrete_choice
shall cover only values in that subtype that satisfy its predicates (see 3.2.4), and each value of that subtype that satisfies its predicates shall be covered by somediscrete_choice
[(either explicitly or by others)].
- If the type of the selecting_
expression
is root_integer, universal_integer, or a descendant of a formal scalar type, then thecase_statement
shall have an othersdiscrete_choice
.
- Otherwise, each value of the base range of the type of the selecting_
expression
shall be covered [(either explicitly or by others)].
Two distinct discrete_choice
s of a case_statement
shall not cover the same value.
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: - 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 thediscrete_choice
others, because others covers all values, even those outside the subtype. 10.c/3 - 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 selecting_
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 nongeneric subtypes that are either unconstrained or nonstatic (or both). It can only happen if there is no othersdiscrete_choice
.
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.Dynamic Semantics
11/3For the execution of a case_statement
, the selecting_expression
is first evaluated.
If the value of the selecting_expression
is covered by the discrete_choice_list
of some case_statement_alternative
, then the sequence_of_statements
of the _alternative
is executed.
Otherwise (the value is not covered by any discrete_choice_list
, perhaps due to being outside the base range), Constraint_Error is raised.
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 can be given explicitly. Examples
15Examples of case statements:
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;
17case Today is
when Mon => Compute_Initial_Balance;
when Fri => Compute_Closing_Balance;
when Tue .. Thu => Generate_Report(Today);
when Sat .. Sun => null;
end case;
18case 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
function_call
s and type_conversion
s are name
s, whereas in Ada 83, they were expression
s. 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.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
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.case_statement
legal: subtype S is Integer range 1..2;
function F return S;
case F is
when 1 => ...;
when 2 => ...;
-- No others needed.
end case;
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 nameable subtype; there is still a perfectly good result subtype, though. Wording Changes from Ada 83
discrete_choice
s and discrete_choice_list
s in 3.8.1, “Variant Parts and Discrete Choices”.expression
is now a complete context. See 8.6, “The Context of Overload Resolution”.type_conversion
s are now defined as name
s, their coverage rule is now covered under the general rule for name
s, rather than being separated out along with qualified_expression
s. Wording Changes from Ada 2005
discrete_choice
s made to allow static predicates (see 3.2.4) as case choices (see 3.8.1).case_expression
, and to clarify which expression
is being talked about in the wording.