Sie sind auf Seite 1von 1

The Joy of

Programming S.G. Ganesh

Duff’s Device and Some Interesting Aspects of Switch


The switch statement appears mundane; what can be special or interesting about it? In this issue, we’ll
explore the switch statement—you may realise that you’ve underestimated its value!

C
/C++ allows only integer types for use in case send(short *to, short *from, int count){
statements. Why can’t we use floating point numbers? do
Because C designers thought that it is not a good idea: *to = *from++;
checking the exact equality in floating point is not portable while(--count>0);
[ref: C99 rationale]. How about string literals? It is allowed in } // this program fails if count is equal to zero.
many languages that evolved from C, such as C#, which is a and this version, compiled in a VAX C compiler, ran
useful feature. Since switch is for integral types, a compiler very slow. The reason is that the compiler translates
can translate it to efficient code, as we will now see. do-while as a pair of two gotos and labels (one for each
Which of the two is better: a switch statement or true and false case); for every condition check, a goto is
cascading if-else statements? Well, a switch expresses executed, which makes it slow. So Tom Duff proposed
the programmer’s intentions more clearly than an if-else another, faster version:
cascade. Also, you might be surprised to know that a switch send(short *to, short *from, int count){
is, in general, more efficient than an equivalent if-else register n=(count+7)/8;
statement sequence! Why? // get number of times to execute do...while loop
The if-else statement is flexible: it can have different switch(count%8){
conditions for each ‘if’ statement; also each condition can // go to the remaining mod value
have (different) variables for comparison in the conditional case 0: do{ *to = *from++;
expression. However, a switch statement is limited: it can case 7: *to = *from++;
have only one condition and the matching of the case case 6: *to = *from++;
statements to the condition expression is always an equality case 5: *to = *from++;
comparison; the case statements are always constant values case 4: *to = *from++;
(and not variables). Because of these reasons, the compiler case 3: *to = *from++;
can do a better job and generate efficient code. How? case 2: *to = *from++;
A sequence of if-else statements is typically translated case 1: *to = *from++;
as a sequence of labels and jump statements (gotos). For a }while(--n>0);
switch statement, a compiler generates an internal table to // this loop is executed n times
find the matches at runtime. Depending on the constants }
in the case statements, the table can be a look-up or range }
table. If the constants are unrelated, the comparison is // this program fails if count is equal to zero.
usually done at the beginning and the jump is made to The idea is to find out the number of times the loop is to
the specific entry in the table (i.e., a look-up table). If be executed in n and call switch to copy for modulus value.
the constants are related and within a range (e.g., ‘0’ to The do-while loop just ignores the case statements since
‘9’), the jump can be made for each range of values (i.e., they are just labels. This technique exploits the fact that
a range table). For example, a Java compiler internally case statements do not break automatically. This version
compiles the switch statements into either lookupswitch ran faster than the do-while loop version (one goto for one
or tableswitch bytecodes. So the switch is typically more statement) because this version has less gotos (only one
efficient than if-else statements (unless the compiler is goto for 8 statements) when the compiler translates it.
very smart, which is unlikely). The efficiency of switch Even though this technique clearly exploits the fall
statements is often exploited in different techniques and through nature of C switch statements, it is (fortunately)
we’ll now look at an unusual case. not widely used; it is good to be aware of this technique,
A source of nasty bugs in C-based languages is that but don’t use it!  
the case statements in the switch statement are fall-
through. The ‘fall-through’ nature of switch is exploited in a S.G. Ganesh is a research engineer in Siemens (Corporate
technique called as Duff’s device [Tom Duff, ‘netnews’, May Technology). His latest book is “60 Tips on Object Oriented
Programming”, published by Tata McGraw-Hill. You can
1984]. The following function which copies count number
reach him at sgganesh@gmail.com
of bytes pointed by from to to:

106 September 2008 | LINUX For You | www.openITis.com

Das könnte Ihnen auch gefallen