This is a remnant of the C programming language. In C switch
is little more than a little syntactic sugar over a goto
depending on the expression value and thus execution simply jumps to the appropriate case
and continues from there. The labels in between are exactly that: labels. They are jump targets but don't affect control flow otherwise and from the compiler's point of view there is nothing in a label that merits a jump elsewhere (except there is INTERCAL's COMEFROM
somewhere). So you have to put an explicit break
after every case where you don't want to fall through to other options.
Java more or less inherited those semantics while eschewing some of the crazier C idioms.
C# on the other hand goes a bit further by disallowing fall-through entirely on non-empty case
labels.
In my opinion though, this was a bit of a design error. Fall-through by default may be much easier to implement in the compiler (because you don't have to add a goto
to the end of the switch
and it aligns very nicely with how things actually work underneath), but in my experience there are vastly more programming errors by accidentally using fall-through than by accidentally not using it.
The most severe design error in my eyes is including the switch
statement with all its weirdness in modern languages.