Ad historie. V asembleru je to natolik odlišné, že by to problémy nezpůsobovalo. Dokladem toho je, že co vím žádný jazyk se syntaxí neodvozenou od C (ať už jde o pascal, python, ruby, plsql, visual basic, fox pro, eifell, perl, bash, C#) nemá příkaz switch s automatickým propadem do další větve. IMHO už to zcela jasně ukazuje, že ta konstrukce v C nebyla volena štastně, když to všichni ostatní mají jinak.
Prostě jako když při if(a=b) dostanu warning, zatímco při if((a=b)) je všechno v pořádku.
Ale vždyť to je přesně ono. Normální je nedělal v ifu přiřazení a jazyk by měl být navržen tak, aby varoval, když děláš něco nestandardního. Ty dvojité závorky tu slouží jako upozornění: ano, vím, že dělám něco nestandardního, něco, co na daném místě není běžné a co může být typo chyba či opomenutí. A proto to explicitně označuji. Pomíjím tedy možnost, že člověk udělá dvojité závorky jen tak, to je u mě čuně a toho nezachrání nic :-)
Stejně tak se v majoritním případě používá case jako rozskok, pokračování do dalšího case je minoritní, a často se dělá chyba v opomenutí break. Proto by měl být jazyk, stejně jako u = a == v ifu, navržen tak, aby standardní zápis vyhodil alespoň varování a umožnil ho explicitně označit za správný (např. formulkou continue, nebo jako v C# goto case x, i když to se mi také moc nelíbí).
Ad C#: Právě proto, že zapomenuté breaky způsobovaly chyby, není v C# legální na konec neuvést nic, vždy tam musí být goto nebo break. Asi jsi se tedy chtěl zeptat, jak se to dělá v perlu, kde lze explicitně přeskočit na další pomocí continue a break je implicitní. No právě pro lidi je přirozené, že větev dalším case končí, takže jim nedělá problém označit explicitně přeskok na jinou větev. Stejně jako by dělali chyby, pokud nějaký jazyk by zaved prioritu sčítání před násobením, tak dělají chyby, když C zavedlo prioritu pokračování před ukončením. Prostě jedna možnost přirozená je, druhá nikoli.
Co se týče C#, ideální to imho také není, je to ale výsledek toho, že se návrháři C# (asi správně) neodvážili u C like jazyka změnit smysl příkazu. Neboť to by způsobilo přesně to, v čem je problém switche v C: člověk automaticky napíše něco co čeká, že se chová tak a ono by se to chovalo jinak.
Zas si ale byli vědomy velké problematičnosti toho konstruktu a tedy přidali bezpečností obstrukci. To, že v podstatě explicitně oproti Javě a C nutí člověka psát "zbytečnosti" jen více jen dokládá, že to problém je. Takže C# řešení je z nouze ctnost.
Tenhle "příkaz" jsem měl na mysli.
Argumentuješ kruhem. Pokud se bavíme o správné sémantice "break" v konstruktu switch, nemůžeš argumentovat sémantikou break v konstruktu switch. A pokud vezmeš všechny ostatní případy, kdy je break použito, vždy jde o cyklus. Naopak ve všech ostatních "necyklových" konstrukcích (if, funkce, blok) příkaz break použít nelze.
Z toho plyne, že break v příkazu switch má nestandardní a posunutou sémantiku (to dokládá i to, že jedině ve switch nelze užít continue na místě break.) Proto nevidím žádný problém, kdyby ta sémantika byla posunuta trochu jinak.
Ono právě to, že nejde jednoduše říct - např. break ukončuje cyklus, ale musíš dát seznam příkazů, které ukončuje, ukazuje na to, že není definováno "konzistentně" (rozuměj u všech příkazů stejně - viz if).
1. Každá větev switche je ukončená breakem, stejně jako každá funkce je ukončená returnem.
2. Pokud nechci aby větev skončila nebo funkce vracela hodnotu, tak tam break nebo return nepíšu.
Rozdíl je ten, že případ 2, pokud nastane omylem, pro funkci kompilátor odchytí (function should return value), ale pro switch nikoli. Pokud se opravdu umíš pohlídat, že nikdy nezapomenš break, tak Tě to ctí. Z praxe se ale ukazuje, že ostatní s tím problémy mají :-)... jak ukazuje i úvodní dotaz v threadu (admini, nejde tu polemiku přesunout do samostatného threadu? :-)).