Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

5.4 Case Statements

[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.] 


case_statement ::= 
   case expression is
   end case;
case_statement_alternative ::= 
   when discrete_choice_list =>

Name Resolution Rules

{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

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.]
The possible values of the expression shall be covered as follows: 
Ramification: Although not official names of objects, a value conversion still has a defined nominal subtype, namely its target subtype. See 4.6
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. 
Two distinct discrete_choices of a case_statement shall not cover the same value. 
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: 
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.
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

{execution (case_statement) [partial]} For the execution of a case_statement the expression is first evaluated.
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.
{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.
Ramification: In this case, the value is outside the base range of its type, or is an invalid representation.
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 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;
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;
case Bin_Number(Count) is
   when 1        => Update_Bin(1);
   when 2        => Update_Bin(2);
   when 3 | 4    =>
   when others   => raise Error;
end case;

Incompatibilities With Ada 83

{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.
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

{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.
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: 
subtype S is Integer range 1..2;
function F return S;
case F is
   when 1 => ...;
   when 2 => ...;
   -- No others needed.
end case;
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

Ada 83 forgot to say what happens for “legally” out-of-bounds values.
We take advantage of rules and terms (e.g. cover a value) defined for discrete_choices and discrete_choice_lists in 3.8.1, “Variant Parts and Discrete Choices”.
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”.
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   References   Search   Previous   Next 
Ada-Europe Sponsored by Ada-Europe