Muitas respostas parecem focar na capacidade de cair como o motivo para exigir a break
declaração.
Acredito que foi simplesmente um erro, devido em grande parte porque quando C foi projetado, não havia quase tanta experiência com a forma como essas construções seriam usadas.
Peter Van der Linden defende seu livro "Expert C Programming":
Analisamos as fontes do compilador Sun C para ver com que frequência a falha padrão foi usada. O front end do compilador Sun ANSI C possui 244 instruções de opção, cada uma com uma média de sete casos. A queda ocorre em apenas 3% de todos esses casos.
Em outras palavras, o comportamento normal da troca está errado 97% das vezes. Não é apenas em um compilador - pelo contrário, onde o fall through foi usado nessa análise foi geralmente para situações que ocorrem com mais frequência em um compilador do que em outro software, por exemplo, ao compilar operadores que podem ter um ou dois operandos :
switch (operator->num_of_operands) {
case 2: process_operand( operator->operand_2);
/* FALLTHRU */
case 1: process_operand( operator->operand_1);
break;
}
A queda de casos é tão amplamente reconhecida como um defeito que até existe uma convenção de comentário especial, mostrada acima, que diz ao fiapo "este é realmente um daqueles 3% de casos em que a queda foi desejada".
Eu acho que foi uma boa ideia para o C # exigir uma instrução de salto explícita no final de cada bloco de caso (enquanto ainda permite que vários rótulos de caso sejam empilhados - desde que haja apenas um único bloco de instruções). No C #, você ainda pode fazer com que um caso caia para outro - você só precisa tornar explícita a queda saltando para o próximo caso usando a goto
.
É uma pena que o Java não tenha aproveitado a oportunidade para romper com a semântica C.