A switch statement executes one of several blocks depending on the value of an expression. The body of the switch statement consists of a list of clauses, each of which consists of a set of case labels and a block. Each of the case labels contains an expression that must evaluate to a single value of a type that conforms to the type of the switch expression (see Section 8.2 for the definition of type conformance). In addition, a switch statement may have a final clause with the label default.
Examples
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
numDays = 31;
case 4: case 6: case 9: case 11:
numDays = 30;
case 2:
if ( ((year % 4 == 0) && !(year % 100 == 0))
|| (year % 400 == 0) ) {
numDays = 29;
}
else {
numDays = 28;
}
default:
WriteLine("Invalid month.");
numDays = 0;
}
Syntax
SwitchStatement(s: SwitchStatement)
= "switch" "(" Expression(s.expression) ")"
"{" { SwitchClause(s.nonDefaultClause) }
[ SwitchDefaultClause(s.defaultClause) ] "}"
SwitchClause(s: SwitchClause)
= SwitchCase(s.case) { SwitchCase(s.case) }
NonEmptyStatementSequence(s.block)
SwitchCase(e: Expression)
= "case" Expression(e) ":"
SwitchDefaultClause(b: Block)
= "default" ":" NonEmptyStatementSequence(b)
NonEmptyStatementSequence(b: Block)
= DocumentedStatement(b.statement) { DocumentedStatement(b.statement) }
Figure 9 51 Abstract Syntax of Switch Statements
Cross References
-
Expression see Subclause 8.1
-
DocumentedStatement see Subclause 9.1
Semantics
Switch Execution
When a switch statement is executed, first the switch expression is evaluated and then all the case expressions are evaluated concurrently. The switch expressions and all case expressions must have a multiplicity upper bound no greater than 1. If the result of any case expression equals the result of the switch expression, then the associated statement sequence is enabled for execution. If more than one statement sequence is enabled, then one of them is non-deterministically selected for execution.
If no case expressions have a result equal to the result of the switch expression, and there is a default clause, then the statement sequence associated with the default clause is executed. Since all the case expressions must be checked before a default clause can execute, the execution of the default clause always happens sequentially after the completion (and failure) of all case tests.
If no case expressions have a result equal to the result of the switch expression, and there is not a default clause, then the switch statement has no further effect.
“Equality” of values is evaluated as for an equality operator (see Subclause 8.6.6).
NOTE. Case expressions are evaluated concurrently, not sequentially, and execution does not “fall through” from one switch clause to the next, as it does in traditional C switch statements. This means that it is not necessary to place a break statement at the end of a switch clause to avoid execution continuing with the next clause. However, placing a break at the end of the clause anyway will not harm the overall execution of the switch statement. (See also Subclause 9.13 on break statements.)
Annotations
The annotations @assured and @determined may be used with a switch statement (see also Subclause 9.2 on annotations). The annotation @assured indicates that the result of at least one clause in the switch statement will always be executed. The annotation @determined indicates that at most one clause will execute. The annotations may be used together, which indicates that exactly one clause will always execute.
Names
New local names may not be defined in case expression, but existing local names may be reassigned. However, the same name may not be assigned in more than one case expression because these expressions are evaluated concurrently, so assignments of the same name in more than one of them could potentially conflict. Assignments made in the case expressions of a switch clause are available in the statement sequence of that clause.
New local names may only be defined in the statement sequences of a switch statement that has a final default clause and then only if the same names are defined in every clause. The type of such names after the switch statement is the effective common ancestor (see the definition in Subclause 8.7) of the types of the name in each clause, with a multiplicity lower bound that is the minimum of the lower bound for the name in each clause and a multiplicity upper bound that is the maximum for the name in each clause.
9.10while Statements
A while statement executes an expression and a block until the value of the expression is false. The expression must have type Boolean and a multiplicity upper bound of 1.
Examples
while ((last = this.list->size()) > 0) {
this.list[last].cleanUp();
this.list->remove(last);
}
while (file.hasMore()) {
nextRecord = file.readNext();
if (nextRecord!=null) {
checksum = ComputeChecksum(checksum, nextRecord);
}
}
Syntax
WhileStatement(s: WhileStatement)
= "while" "(" Expression(s.condition) ")" Block(s.body)
Figure 9 52 Abstract Syntax of while Statements
Cross References
-
Expression see Subclause 8.1
-
Statement see Subclause 9.1
-
Block see Subclause 9.1
Semantics
When a while statement is executed, its expression is evaluated. If the expression evaluates to false, the execution of the while statement is complete. Otherwise, its block is executed, and then the entire while statement is executed again, beginning with re-evaluating the expression.
Names
Local names defined within the condition expression of a while statement are available within the body block of the while statement, with the value as computed on each iteration of the loop. They are also available after completion of execution of the while statement, with the values assigned as of the last evaluation of the while condition expression.
Local names within the body block of a while statement may be used within that block, but they are prohibited from being used outside the block. This is because they could be uninitialized if the while statement does not execute its body.
Local names defined before a while statement may be reassigned within the while statement. After completion of execution of the while statement, they have the values assigned as of the last evaluation of the while statement.
Share with your friends: |