Win a copy of Design for the Mind this week in the Design forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Purpose of "fall through" in switch block

 
Geeta Sawant
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why is it that all case statements get excuted after a match and when no break is given in a case statement?
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because that is how the language was designed.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24208
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And that's because C was designed that way, and the syntax is taken from C.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Now the question is, of course: why was C designed that way?

Any ideas?
 
Edwin Keeton
Ranch Hand
Posts: 214
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because that's the way assembly language works
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suppose in the most ancient switch statements painted on cave walls the numeric value that we switch upon is an index into machine instructions. Compute the next instruction address by adding the index to the start of the table and jump there. Once you've jumped it would be natural to keep going right through the following instructions until told otherwise, which is the break. It's way too close to assembly language for my tastes. Leaving out a "break" is much too easy. There is supposedly some performance advantage over if-else, but that doesn't win me over. Even COBOL has a far superior syntax for choosing which block of code to run.
 
Jeff Albertson
Ranch Hand
Posts: 1780
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I was learning C, I was taught that switch was defined that way so
that you could have multiple case labels for the same code:

Here, case 0 trivially falls through to case 1, because case 0
lacks a break (or anything else). On the other hand, it would
have been nice if Java had extended the case syntax to allow one
to write "case 0,1:", but it's too late to change now...
 
Kenneth Albertson
Ranch Hand
Posts: 59
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For the benefit of those who care about such historical trivia ...

From Ken Arnold, James Gosling & David Holmes, 2000, The Java Programming Language, 3rd ed, Addison-Wesley, pp 184-5:
Falling through to the next case can be useful in some circumstances. But in most cases a break should come after the code that a case label selects. Good coding style suggests that you always use some form of FALLTHROUGH comment to document an intentional fall-through.

... You should terminate the last group of statements in a switch with a break, return or throw, as you would a group of statements in an earlier case. Doing so reduces the likelihood of accidentally falling through the bottom of what used to be the last part of the switch when a new case is added.
And from Brian Kernighan & Dennis Ritchie, 1988, The C Programming Language, 2nd ed, Prentice Hall, p 59:
Falling through cases is a mixed blessing. On the positive side, it allows several cases to be attached to a single action ... But it also implies that normally each case must end with a break to prevent falling through to the next. Falling through from one case to another is not robust, being prone to disintegration when the program is modified. With the exception of multiple labels for a single computation, fall-throughs should be used sparingly, and commented.

As a matter of good form, put a break after the last case ... even though its logically unnecessary. Some day when another case gets added at the end, this bit of defensive programming will save you.
It's a while since that book last came down off the shelf! For any youngsters who have read this far, and don't know why Dennis Ritchie's opinions about the C switch statement should be of interest, he designed and first implemented C, after which he and Ken Thompson (no relation) used it to create an operating system that came to be called unix.
 
Jos AH
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Kym Thompson:
For any youngsters who have read this far, and don't know why Dennis Ritchie's opinions about the C switch statement should be of interest, he designed and first implemented C, after which he and Ken Thompson (no relation) used it to create an operating system that came to be called unix.


Maybe this is a nice read for anyone interested in the etymology of that programming language.

kind regards,

Jos
[ October 14, 2005: Message edited by: Jos AH ]
 
Rick Beaver
Ranch Hand
Posts: 464
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Consider a car factory - they make a number of models of car - starting with a basic entry model and increasing up to a luxury business class model.

Consider a switch statement that added features to a model based on it's type (how luxurious it was).

With the fall through behaviour you can do this:


[/code]
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Where's Gerald? That structure makes inheritance completely unnecessary!
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Stan James:
I suppose in the most ancient switch statements painted on cave walls the numeric value that we switch upon is an index into machine instructions. Compute the next instruction address by adding the index to the start of the table and jump there. Once you've jumped it would be natural to keep going right through the following instructions until told otherwise, which is the break. It's way too close to assembly language for my tastes. Leaving out a "break" is much too easy. There is supposedly some performance advantage over if-else, but that doesn't win me over. Even COBOL has a far superior syntax for choosing which block of code to run.


The performance advantage is exactly what you described here. With a switch statement, the assembly instructions (or byte codes) jump directly to the code to be executed. With an if...else if...else chain, each condition is checked before determining what instructions to execute. This means that if...else runs in time linear to the number of choices (i.e. O(n)) whereas switch runs in constant time (i.e. O(1)). This seems like a significant improvement especially if the switch statement is in the middle of a loop that is executed many times.

Layne
[ October 14, 2005: Message edited by: Layne Lund ]
 
Jos AH
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's the sickest reason why fall-through can be handy. Tom Duff once stared at a piece of code of his own hand and wasn't happy with the performance. This was it:


The 'to' pointer contained the address of a memory mapped device. 'count' shorts had to fed to it, starting at address 'from'. Using 'loop unrolling', Tom Duff came up with the following diabolical solution:

That day, the (in)famous "Duff's Device" was born.

kind regards,

Jos
[ October 16, 2005: Message edited by: Jos AH ]
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fallthrough works very well for state machines and procedural behaviors.



not totally complete example but I use this type of thing all the time when I write code for such things as RF receivers and anti-theft modules in c. In general doStuff would be called by the main program thread every 20ms. Until you get the door open you dont sit down. But you cant hold up the program waiting on the door to open, so you give it 1 shot and exit out and do the rest of the program. Next time you enter the state machine at the same place which is wherever you left off. If you do get the door open its on to the next step. If you did not fall through you would get to the next step the next time the method is called which is in another 20ms. Which is sometimes not acceptable.

[ October 16, 2005: Message edited by: Mr. C Lamont Gilbert ]
OK, hate to leave it like that. Sometimes we get a requirement to get the whole procedure done in < 300ms. And there are other time critical procedures the module has to do as well. In my field we don't like to spend money and we have little energy available, so we use small slow processors. Every tic counts.
[ October 16, 2005: Message edited by: Mr. C Lamont Gilbert ]
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Guess I'd have to look at the byte code, but it seems the jump performance advantage works only if it's easy to calculate where to jump from the value. If I switch on values of 0, 131, 437000 and 11000000 there has be be a lookup table from my values to jump offsets. I'm sure there is some kind of smart hashing or indexing that makes it faster than a linear if-else setup, but I'm skeptical that it's enough faster to matter much to me unless I'm doing bazillions of trips through a loop. So far it's not been enough to make me use a switch case instead of something else I thought was more readable.

Interestingly for the last compiler I looked at (in the 80s) the COBOL structure I liked so much generated extra instructions compared to if-else. Dope slap for the compiler team, unless they were doing something way over my head - completely possible.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic