Warum verwenden Sprachen keine expliziten Fall-through-Anweisungen für switch-Anweisungen?

17

Ich las Warum wir verwenden müssen breakin switch? , und ich habe mich gefragt, warum implizites Durchfallen in einigen Sprachen (wie PHP und JavaScript) zulässig ist, während explizites Durchfallen (AFAIK) nicht unterstützt wird.

Es ist nicht so, dass ein neues Schlüsselwort erstellt werden müsste, wie continuees vollkommen angemessen wäre, und es würde alle Unklarheiten darüber lösen, ob der Autor beabsichtigt, dass ein Fall zustande kommt.

Das derzeit unterstützte Formular lautet:

switch (s) {
    case 1:
        ...
        break;
    case 2:
        ... //ambiguous, was break forgotten?
    case 3:
        ...
        break;
    default:
        ...
        break;
}

In der Erwägung, dass es sinnvoll wäre, geschrieben zu werden als:

switch (s) {
    case 1:
        ...
        break;
    case 2:
        ...
        continue; //unambiguous, the author was explicit
    case 3:
        ...
        break;
    default:
        ...
        break;
}

Lassen Sie uns zu Zwecken dieser Frage die Frage ignorieren, ob Fall-Throughs ein guter Codierungsstil sind oder nicht.

Gibt es Sprachen, die das Durchfallen erlauben und die es explizit gemacht haben?

Gibt es historische Gründe, switchdie implizites Durchfallen statt explizites zulassen?

zzzzBov
quelle
4
C # erfordert, dass Sie explizit goto casedamit umgehen, sodass die Prämisse Ihrer Frage ein bisschen falsch ist.
pdr
1
@pdr, ich habe sehr explizit gefragt, ob es Sprachen gibt, die bereits Fall-Through unterstützen, was mir goto casein C # nicht bekannt war .
zzzzBov
Ja, tut mir leid, ich habe versäumt, dass Ihre Frage aus zwei Teilen besteht. Leider stimme ich zu, um zu schließen, weil es einer Abstimmungsfrage sehr nahe kommt. Es wird viele richtige Antworten geben.
pdr
Mit C # können Sie auch festlegen, dass mehrere Beschriftungen dieselbe Anweisungsliste verwenden, wodurch einige Situationen beseitigt werden, die ein Durchfallen erfordern. Im übrigen hat es goto case, wie pdr erwähnt.
Brian

Antworten:

20

Es ist in erster Linie historisch, die meisten Sprachen haben nur das kopiert, was C getan hat.

Der Grund, warum C dies tat, ist, dass die Ersteller von C beabsichtigten, Switch-Anweisungen einfach in eine Sprungtabelle zu optimieren. Dies ist auch der Grund, warum C switch-Anweisungen auf ganzzahlige Werte begrenzt.

In einer Sprungtabelle berechnet das Programm anhand des Ausdrucks, zu welcher Position gesprungen werden soll. Das Programm springt zu diesem Punkt und setzt die Ausführung ab diesem Punkt fort. Wenn Sie den Rest der Tabelle überspringen möchten, müssen Sie einen Sprung zum Ende der Tabelle einfügen. C verwendet explizite breakAnweisungen, damit eine direkte Entsprechung zu diesem Konstrukt besteht.

Dirk Holsopple
quelle
7
Als kleine Anmerkung erwähnt Peter van der Linden in seinem Buch "Expert C Programming", dass während er für Sun an seinem C-Compiler arbeitete, ungefähr 97% der Switch-Fälle enthalten breakund nur weniger als 3% durchgefallen sind . Anschließend verwendete er dies als Beispiel dafür, dass das standardmäßige Fall-Through-Verhalten nicht intuitiv ist und besser umgekehrt sein sollte (verwenden Sie ein Schlüsselwort, um explizites Fall-Through anzugeben). Oh, und das Buch ist wirklich großartig darin, andere Kuriositäten von C zu erklären, von denen einige auch in C ++ und sogar in C # und Java zu finden sind! Es ist alles in B und BCPL verwurzelt. :)
zxcdw
3
Es gibt Programmiersprachen, bei denen der Durchbruch eindeutig ist, wie z . B. c # ( msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx ). Auf der anderen Seite ist break auch in c # explizit.
Linkerro
@zxcdw: Schade, es gibt keine Möglichkeit, dass ein kleiner Vogel in der Zeit zurückgeht und vorschlägt, dass jedem Etikett case, das als das erste gekennzeichnet ist, automatisch ein Präfix vorangestellt breakwird, denen jedoch +case(oder einem anderen solchen Bezeichner) nicht. Das wäre für einen Compiler leicht zu handhaben gewesen und hätte die semantischen Vorteile der vorliegenden Anordnung zugelassen, während viele Codezeilen beseitigt worden wären.
Supercat
7

Go ermöglicht die explizite Verwendung des fallthroughSchlüsselworts break (break ist implizit, kann aber explizit sein):

switch val {
case 1: // breaks
case 2:
    fallthrough
case 3:
    goto 
case 4, 5, 6: // equivalent to defining individual cases with explicit fallthough
    break // unnecessary
default:
}

Hier ist das relevante Bit von Effective Go und die Sprachspezifikation .

Ich glaube nicht, dass Sie dazu verwenden können goto, zu einem bestimmten Fall zu wechseln, aber Sie können ein Etikett im Inneren des Falls anbringen und ein gotonormales Etikett verwenden .

Als Bonus kann Go Sie binäre Ausdrücke, Strings oder verwenden Typen in einem Switch als case - Anweisungen.

Beatgammit
quelle