¿Por qué los lenguajes no utilizan la caída explícita en las declaraciones de cambio?

17

Estaba leyendo ¿Por qué tenemos que el uso breakde switch? , y me llevó a preguntarme por qué se permite la caída implícita en algunos lenguajes (como PHP y JavaScript), mientras que no hay soporte (AFAIK) para la caída explícita.

No es como si fuera necesario crear una nueva palabra clave, ya continueque sería perfectamente apropiado y resolvería cualquier problema de ambigüedad sobre si el autor quería que un caso fracasara.

El formulario actualmente admitido es:

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

Mientras que tendría sentido que se escribiera como:

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

Para los propósitos de esta pregunta, ignoremos la cuestión de si los fall-through son un buen estilo de codificación.

¿Existen idiomas que permitan la caída y lo hayan hecho explícito?

¿Hay alguna razón histórica que switchpermita la caída implícita en lugar de explícita?

zzzzBov
fuente
44
C # requiere que seas explícito goto case, por lo que la premisa de tu pregunta es un poco errónea.
pdr
1
@pdr, pregunté muy explícitamente si había algún lenguaje que ya admitiera fall-through, no lo sabía goto caseen C #.
zzzzBov
Sí, lo siento, perdí que tu pregunta tuviera dos partes. Desafortunadamente, como está dicho, estoy votando para cerrar porque está muy cerca de una pregunta de la encuesta. Habrá muchas respuestas correctas.
pdr
C # también le permite que varias etiquetas compartan la misma lista de instrucciones, lo que elimina algunas de las situaciones que requieren fallas. Por lo demás, tiene goto case, como menciona pdr.
Brian

Respuestas:

20

Es principalmente histórico, la mayoría de los idiomas simplemente copiaron lo que hizo C.

La razón por la que C lo hizo así es que los creadores de C pretendían que las declaraciones de cambio fueran fáciles de optimizar en una tabla de salto. Esta es también la razón por la que C limita las declaraciones de cambio a valores integrales.

En una tabla de salto, el programa calculará a qué posición saltar en función de la expresión. El programa saltará a ese punto y luego continuará ejecutándose desde ese punto. Si desea omitir el resto de la tabla, debe incluir un salto al final de la tabla. C usa breakdeclaraciones explícitas para que haya una correspondencia directa con esta construcción.

Dirk Holsopple
fuente
77
Como pequeña nota, en su libro "Expert C Programming", Peter van der Linden menciona que mientras trabajaba para Sun en su compilador C, aproximadamente el 97% de los casos de conmutadores contenían breaky solo menos del 3% fueron fallidos . Luego usó esto como un ejemplo de que el comportamiento de falla predeterminado es contra-intuitivo y sería mejor ser inverso (use una palabra clave para indicar una falla explícita). ¡Ah, y el libro es realmente genial para explicar otras rarezas de C también, algunas de las cuales se encuentran en C ++ e incluso en C # y Java también! Todo está enraizado en B y BCPL. :)
zxcdw
3
Hay lenguajes de programación donde la caída es explícita, como c # ( msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx ). Por otro lado, la ruptura también es explícita en c #.
linkerro
@zxcdw: Lástima que no haya forma de que un pajarito pueda retroceder en el tiempo y sugerir que cualquier etiqueta marcada case, que no sea la primera, debe tener el prefijo automático automáticamente break, pero las marcadas +case(o algún otro designador similar) no deberían. Eso habría sido fácil de manejar para un compilador y habría permitido las ventajas semánticas de la disposición actual, al tiempo que eliminaba muchas líneas de código.
supercat
7

Go permite una caída explícita mediante la fallthroughpalabra clave (el salto es implícito, pero puede ser explícito):

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

Aquí está el bit relevante de go efectivo y la especificación del idioma .

No creo que pueda usar gotopara ir a un caso específico, pero puede hacer una etiqueta dentro de la caja y usar una gotonormal.

Como beneficio adicional, Go le permite usar expresiones binarias, cadenas o tipos en un interruptor como declaraciones de casos.

beatgammit
fuente