Re:The security hole in sudo
by EvanAnderson on Wednesday May 23, 2012 @10:55AM
(#4013322)
I've always felt like the switch statement's "break" behavior should have been the implicit case, with a statement to trigger fallthrough if you really wanted it. I wonder what percentage of the time fallthrough is actually desired in switch statements. I would assume it's wildly in the minority.
[ Parent
| on HN ]
Makes total sense when you remember C's assembly roots. On most architectures including the PDP-11, the program counter just moves to the next instruction. To make it do anything different, you need a jump instruction, and that's what the "break" means.
To a sibling comment: C# does permit fallthrough, just with ugly syntax. You can "goto case 2". http://stackoverflow.com/questions/174155/switch-statement-f...
Re:The security hole in sudo
by AlexFromBelgium on Wednesday May 23, 2012 @02:04PM
(#4014390)
Douglas Crockford said in one of his talk on Javascript (www.yuiblog.com/crockford/) that the syntax came from Fortran. And indeed it's because assembly did the fall through thing...
I agree. In Go break is the default, and there's an explicit 'fallthrough' statement.
Go was not designed to be portable assembler. break directly maps to a jump statement in assembler. fallthrough does not. Since C is designed to be portable asembler, it makes sense to include break as a keyword instead of a fallthrough keyword (and break would still be needed anyway for for loops and while loops).
C# doesn't have fallthrough at all, but it won't compile without "break;". I'm really not sure what they were going for there.
You can "goto" any case label in C#, which works like fallthrough but is more flexible (since you can jump anywhere). At the same time, it avoids the refactoring hazard associated with fallthrough, in which changing the order of the switch labels can change the behavior of the code. Of the languages that have "switch" (not counting ML/Haskell-style pattern matching here), C#'s approach seems ideal.
The C# approach sounds like a recipe for abuse:
switch(something)
{
case 1:
// Do stuff
goto case 4;
case 2:
// Do stuff
goto case 1;
case 3:
// Do stuff
goto case 5;
case 4:
// Do stuff
goto case 3;
case 5:
// Do stuff
break;
}
Re:The security hole in sudo
by PotatoEngineer on Thursday May 24, 2012 @01:22PM
(#4019472)
That's quite horrible! Fortunately, it's obviously horrible, and since "goto" has such a stigma attached to it, programmers will only use it when it's necessary. (Cross your fingers.)
register_globals would like to have a word with you.
I agree that removing implicit fallthrough is good, since it's a 90%/10% feature, but my problem is that the "break;" is meaningless extra syntax, since the lack of it generates a compiler error.
C# already implies no implicit fallthrough, so there's no need to explicitly state that you're not falling through. A better solution (for every language, really) would be a "fallthrough;" statement or "goto case x;", which C# does get right.
Re:The security hole in sudo
by TazeTSchnitzel on Wednesday May 23, 2012 @11:26AM
(#4013504)
So Java and C++ programmers don't panic and think the whole thing will fall through.
switch (v) {
case FOO_A:
case FOO_B:
do some_foo();
break; // if you really want :P
case BAR_X:
case BAR_Y:
do_some_bar();
}
Here you have two implicit fallthroughs used for cleaner code.Another use is to express one case as a subset or superset of another case:
switch (v) {
case FOO_BAR:
do_some_foo();
case BAR:
do_some_bar();
/*...*/
}
IIRC, there was some C-like programming language out there (C# probably?) which only provided default fallthrough if there was no code between the cases, as in the above example.You're defending against a different claim. The idea is not that C's current way of doing things has no advantages, the idea is that it's not the optimal way. Pointing out a case in which it happens to initially be more helpful is basically a no-op. And I can think of better ways to spell even what you have there. Consider a "cases FOO_A, FOO_B" construct or something that both makes explicit what you are trying to do and still retains default break behavior. Fewer characters, clearer semantics, not hard to format for easy reading. C's way is definitely not optimal even on its own terms.