Perché le lingue non usano il fall-through esplicito sulle istruzioni switch?


17

Stavo leggendo Perché dobbiamo usare breakin switch? e mi ha portato a chiedermi perché in alcune lingue (come PHP e JavaScript) sia consentito il fall-through implicito, mentre non esiste supporto (AFAIK) per il fall-through esplicito.

Non è come se fosse necessario creare una nuova parola chiave, come continuesarebbe perfettamente appropriato, e risolverebbe qualsiasi problema di ambiguità sul fatto che l'autore intendesse far passare un caso.

Il modulo attualmente supportato è:

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

Considerando che avrebbe senso che fosse scritto come:

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

Ai fini di questa domanda, ignoriamo la questione se i fall-through siano o meno un buon stile di codifica.

Esistono lingue che consentono il fall-through e lo hanno reso esplicito?

Ci sono ragioni storiche che switchconsentono un fallito implicito anziché esplicito?


4
C # richiede di essere esplicito goto case, quindi la premessa della tua domanda è un po 'sbagliata.
pdr,

1
@pdr, ho chiesto in modo molto esplicito se c'erano già delle lingue che supportavano fall-through, di cui non ero a conoscenza goto casein C #.
zzzzBov,

Sì, scusa, mi sono perso che c'erano due parti della tua domanda. Sfortunatamente, così com'è, sto votando per chiudere perché è molto vicino a una domanda del sondaggio. Ci saranno molte risposte giuste.
pdr,

C # consente inoltre a più etichette di condividere lo stesso elenco di istruzioni, eliminando alcune delle situazioni che richiedono il fall-through. Per il resto goto case, come dice il pdr.
Brian,

Risposte:


20

È principalmente storico, la maggior parte delle lingue ha appena copiato ciò che ha fatto C.

La ragione per cui C ha fatto in questo modo è che i creatori di C intendevano che le istruzioni switch fossero facili da ottimizzare in una tabella di salto. Questo è anche il motivo per cui C limita le istruzioni switch a valori integrali.

In una tabella di salto, il programma calcolerà la posizione a cui saltare in base all'espressione. Il programma salterà a quel punto e quindi continuerà l'esecuzione da quel punto. Se vuoi saltare il resto del tavolo devi includere un salto alla fine del tavolo. C usa breakdichiarazioni esplicite in modo che vi sia una corrispondenza diretta con questo costrutto.


7
Come piccola nota, nel suo libro "Expert C Programming", Peter van der Linden menziona che mentre lavorava per Sun sul loro compilatore C, circa il 97% dei casi di switch contenuti breake solo meno del 3% erano in rovina . Ha quindi usato questo come esempio che il comportamento di fall-through predefinito è contro-intuitivo e sarebbe meglio essere inverso (usare una parola chiave per indicare un fall-through esplicito). Oh, e il libro è davvero ottimo per spiegare anche altre stranezze di C, alcune delle quali si trovano in C ++ e persino in C # e Java! È tutto radicato in B e BCPL. :)
zxcdw,

3
Esistono linguaggi di programmazione in cui fall through è esplicito, come c # ( msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx ). D'altra parte, anche la rottura è esplicita in c #.
linkerro,

@zxcdw: Peccato che non ci sia modo in cui un piccolo uccello possa tornare indietro nel tempo e suggerire che qualsiasi etichetta contrassegnata case, diversa dalla prima, dovrebbe essere automaticamente preceduta da prefissi break, ma quelli contrassegnati +case(o qualche altro simile designatore) non dovrebbero. Sarebbe stato facile per un compilatore gestire e consentire i vantaggi semantici della presente disposizione, eliminando nel contempo molte righe di codice.
supercat

7

Go consente l'espansione esplicita utilizzando il fallthrough parola chiave (interruzione è implicita, ma può essere esplicita):

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:
}

Ecco la parte rilevante di go efficace e le specifiche della lingua .

Non penso che tu possa usare gotoper andare a un caso specifico, ma puoi creare un'etichetta all'interno del caso e usare un gotonormale.

Come bonus, Go ti consente di utilizzare espressioni binarie, stringhe o tipi in un interruttore come istruzioni di caso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.