4 ms·
This is a great example of the dangerous syntax of Switch statements in C. However, I do think programmers should not reflexively avoid Switch/Case statements
by georgeecollins 6y ago
This is a great example of the dangerous syntax of Switch statements in C. However, I do think programmers should not reflexively avoid Switch/Case statements in their code. Polymorphism is often a way of writing switch statements that looks very clean, but hides some of the same spooky branching behavior. The nice thing about a switch/branch is you can see where the code might go from the text in front of you.
- marcosdumay 6y agoIn C? No, C developers should reflexively avoid switch statements, and only fight this reflex after a serious risk evaluation (and very likely, after a lot of tests are written). Like macros, C switch is too powerful and dangerous to use on a whim.
- simias 6y agoI sorta see where you're coming from, but I can't really see myself avoiding switch entirely in C. I do agree that it's very poorly designed since it makes it very easy to shoot yourself in the foot. It does make it very nice to write some things, in particular state machines. It can even be less error prone in these situations since compilers will (sometimes) warn if you don't match all possible values of an enum, which is nice if you add a state to your machine and forget to update it everywhere. Fortunately these days there are compiler warnings to alleviate some of the risks. GCC with -Wextra will warn if you have an unmarked fallthrough in a switch for instance (but not with -Wall). But beyond that I do agree that if I could go back in time and tell Dennis Ritchie to change some things about the language "make switch break by default and add a fallthrough keyword when you actually want the behaviour" would be very high on the list. I get why he made it that way in the first place (if you implement switch/case in assembly with a jump table you get basically the same behaviour by default and you need additional code to break) but it makes for poor ergonomics in C.
- AnimalMuppet 6y agoBaloney. There is absolutely no need to reflexively avoid switch statements. Just don't do this kind of garbage with them.
- marcosdumay 6y agoAnd never forget a break. And triple check the type of those case labels. And keep them short, so all of the above is verifiable. Or, alternatively, you can default to some syntax where the compiler will help you, and leave switches to use with care only where they bring a huge gain.
- StillBored 6y agoLack of 'break' is a very useful bit of syntax I use somewhat frequently for categorization. AKA you have a handful of case values that fall into a smaller subset of catagories. Rather than an unreadable set of if/else's that all have multiple if "a||b||c||d.." conditions, vs a big state machine, or match structure. Then if one enforces a clearer formatting style than is common on most open source projects the lack of "break" statements stick out visually and it becomes much harder to miss a break statement when the intentionally missing ones have lines like "// Intentional fall-through" Or you use a "nobreak" macro and enforce the use of break/nobreak in the automated style/linter.
- touisteur 6y agoBut if you had a syntax that allowed inner/embedded functions, exhaustive matching, and the ability to combine a|b..e, you might never ever EVER need fallthrough. The case statement in Ada is the best control flow structure (I'm not very familiar with advanced FP-style pattern matching, but I can read and follow Ada's with almost closed eyes, and they're exhaustive by default you won't compile until you've handled all the cases), and Ada2012 added case- and if-expressions, and now it seems there's some ongoing work on making it a bit more powerful... This kind of construction makes the power of enumerated types, and restricted range types so much more evident.
- StillBored 6y agoWithout a doubt, even pascal's case statement is better syntactically. It also happens to be more terse.
- brundolf 6y agoC is one of those languages (like JavaScript, arguably) that's stuffed full of so many foot-guns you can't possibly hope to make them all statically impossible. So strong conventions need to exist no matter what, and "don't put case statements below the first block" seems like an easy enough one to visually enforce.
- lmilcin 6y agoI also think that every tool has its purpose. Just because it can be misused isn't reason to banish it altogether. In the end, readability and maintainability of the code is primary concern. I don't really care for those fads that say "you should absolutely ban switch statements". I look at these as a collection of tools that help me make the code more readable. Usually radical statements like this come from people that will take the simple naive code and make it completely incomprehensible for exactly opposite effect that the "best practice" was supposed to achieve. Heck, there are even good uses for goto that make the code more readable as long as you follow accepted convention and don't try to be fancy with it. When I spent couple of years working on embedded ANSI C applications I often used it to make complicated inner loops (like reading and parsing input from device) more readable.