Updated Documentation

  • documentation being revised
  • open to comments

switch Statement


Follow the rule that each value <val> used to select cases in a switch statement is unique. Bad things will happen if you break this rule.

If you have a duplicate <val> in a switch statement you may get a crash or an error message that looks like one of:

  1. A machine-level exception occurred during execution of this statement (signal 11)
  2. duplicate values in a switch: C_HANDLE and C_HANDLE
  3. <0063>:: duplicate case value used. case POINTER, HANDLE

That makes three different messages for what should be one error message. There seems to be a bug in the error reporting.

Bad Example:

The switch syntax is being used incorrectly--this example must fail.

include std/dll.e   
-- this fails  
switch 1 do   
case C_HANDLE then   
case C_POINTER, C_HANDLE then   
end switch   
-- on 32-bit OE4.1 
--> duplicate values in a switch: C_HANDLE and C_POINTER  
-- on 64-bit OE4.1 
--> A machine-level exception occurred during execution of this statement (signal 11) 

The mystery is in the error reporting.

You can write a switch statement that fails:

  • A machine-level exception occurred during execution of this statement (signal 11)

This problem may have something to do with how pointers are used internally by the interpreter.

Bad Example:

This example looks like it should work. No obvious answer for the failure.

constant expr = cos(0) 
constant val = expr 
switch expr do  
    case val then  
        puts(1, "expr = val \n" )  
    case else  
        puts(1, "no match! \n")  
end switch  
-- this example fails when interpreted, but runs correctly when compiled 

It is also true that there are users of the switch statement that do not have problems.

Need to know:

The case <val> must be literal, or a constant assigned its value from a literal, or an enum. It is a bad idea to assign val values by calling a function, it is likely to cause unpredictable results. And of course, they should never be declared as atoms, integers, sequences, or objects.

constant val1 = 1      -- good 
enum val1              -- good, since enums begin with 1 
constant val1 = cos(0)  
constant val2 = cos(0) -- bad, works when compiled, crashes interpreter 
constant val1 = cos(0)  
constant val2 = val1   -- bad, only works when compiled 
atom val = 1           -- bad, since atoms are variables, as are integers and objects 

In the simplest switch statement one case runs, or no cases run:

  1. one expression <expr> is evaluated
  2. the expression <expr> is compared against a series of "n" unique literal values <val1>|<val2>|...|<valn>
  3. a case occurs when an expression and a value matches
    then the code for that case is allowed to run
switch <expr> do 
    case <val1> then 
    case <val2> then 
end switch 

# every value is known in advance 
VALUE := literal_atom | literal_string | constant | enum 
val1 := VALUE 
val2 := VALUE 
# every value is unique  
val1 != val2 

You can distribute unique <val> items between case branches in any way you wish. You can have a case with a list of <val> items. Remember, each <val> is a unique value.

The actions possible in a switch statement are known before a program runs. This means the interpreter (or compiler) is able to optimize for performance.

You can write equivalent code using a switch or using if..elsif.. statements:

switch statement
if elsif statement

atom a = 1
switch a do
case 1 then
? a
case 2 then
? a
end switch

atom a = 1
if    a = 1 then
? a
elsif a = 2 then
? a
end if

Nice to know

You can write a switch statement with more features.

  • a case else branch
    runs when the <expr> does not match any <val>
  • the fallthru keyword
    allows the code in the following case branch to run
  • the break keyword
    jumps you out of a switch statement
  • you can "label" a switch statement
    when you nest switch statements this allows break "label" to specify which switch statement you are jumping out


Quick Links

User menu

Not signed in.

Misc Menu