Pourquoi les langues n'utilisent-elles pas une fonction d'interruption explicite sur les instructions switch?

17

Je lisais Pourquoi devons-nous utiliser breakdans switch? , et cela m'a amené à me demander pourquoi le passage implicite est autorisé dans certains langages (tels que PHP et JavaScript), alors qu'il n'y a pas de support (AFAIK) pour le passage explicite.

Ce n'est pas comme si un nouveau mot clé devait être créé, ce continuequi serait parfaitement approprié, et résoudrait tout problème d'ambiguïté quant à savoir si l'auteur voulait qu'un cas tombe.

Le formulaire actuellement pris en charge est:

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

Attendu qu'il serait logique qu'il soit écrit comme suit:

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

Pour les besoins de cette question, ignorons la question de savoir si les relais sont un bon style de codage.

Existe-t-il des langages qui permettent le basculement et le rendent explicite?

Y a-t-il des raisons historiques qui switchpermettent une chute implicite plutôt qu'explicite?

zzzzBov
la source
4
C # nécessite que vous soyez explicite avec goto case, donc la prémisse de votre question est un peu fausse.
pdr
1
@pdr, j'ai très explicitement demandé s'il y avait des langages qui prenaient déjà en charge la fonction Fall-Through, je n'étais pas au courant goto caseen C #.
zzzzBov
Oui, désolé, j'ai raté qu'il y avait deux parties à votre question. Malheureusement, tel qu'il est, je vote pour clore car c'est très proche d'une question de sondage. Il y aura beaucoup de bonnes réponses.
pdr
C # vous permet également d'avoir plusieurs étiquettes partageant la même liste d'instructions, ce qui supprime certaines des situations qui nécessitent une interruption. Pour le reste, il l'a goto case, comme le mentionne pdr.
Brian

Réponses:

20

C'est principalement historique, la plupart des langages ont juste copié ce que C a fait.

La raison pour laquelle C l'a fait de cette façon est que les créateurs de C voulaient que les instructions de commutation soient faciles à optimiser dans une table de saut. C'est également la raison pour laquelle C limite les instructions de commutation aux valeurs intégrales.

Dans une table de sauts, le programme calculera la position vers laquelle sauter en fonction de l'expression. Le programme va sauter à ce point puis continuer à s'exécuter à partir de ce point. Si vous voulez sauter le reste du tableau, vous devez inclure un saut à la fin du tableau. C utilise des breakinstructions explicites pour qu'il y ait une correspondance directe avec cette construction.

Dirk Holsopple
la source
7
Comme une petite note, dans son livre "Expert C Programming", Peter van der Linden mentionne que pendant qu'il travaillait pour Sun sur leur compilateur C, environ ~ 97% des cas de commutation contenaient breaket seulement moins de 3% étaient de chute. . Il a ensuite utilisé cela comme exemple que le comportement de défaut par défaut est contre-intuitif et qu'il serait préférable qu'il soit inversé (utilisez un mot-clé pour indiquer un passage explicite). Oh, et le livre est vraiment excellent pour expliquer d'autres bizarreries de C aussi, dont certaines se trouvent en C ++ et même en C # et Java aussi! Tout est enraciné dans B et BCPL. :)
zxcdw
3
Il existe des langages de programmation où le passage est explicite, comme c # ( msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx ). En revanche, la rupture est également explicite en c #.
linkerro
@zxcdw: Dommage qu'il n'y ait aucun moyen qu'un petit oiseau puisse remonter dans le temps et suggérer que toute étiquette marquée case, autre que la première, devrait être automatiquement préfixée break, mais pas celles marquées +case(ou un autre tel). Cela aurait été facile à gérer pour un compilateur et aurait permis les avantages sémantiques du présent arrangement, tout en éliminant de nombreuses lignes de code.
supercat
7

Go permet une reprise explicite à l'aide du fallthroughmot clé (break est implicite, mais peut être explicite):

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

Voici le morceau pertinent de go efficace et la spécification de langue .

Je ne pense pas que vous puissiez utiliser gotopour accéder à un cas spécifique, mais vous pouvez créer une étiquette à l'intérieur du boîtier et utiliser une gotonorme similaire.

En prime, Go vous permet d'utiliser des expressions binaires, des chaînes ou des types dans un commutateur en tant qu'instructions de cas.

beatgammit
la source