standard name estandar codificacion code coding-style switch-statement

coding style - name - Cambie la declaración Fallthrough... ¿debería permitirse?



java package name convention (12)

Durante el tiempo que puedo recordar, he evitado usar la sentencia switch fallthrough. En realidad, no puedo recordar que alguna vez haya entrado en mi conciencia como una posible forma de hacer las cosas, ya que me fue enseñado en la cabeza que no era más que un error en la declaración del interruptor. Sin embargo, hoy encontré un código que lo usa por diseño, lo que me hizo preguntarme inmediatamente qué piensan todos los miembros de la comunidad acerca de la declaración de cambio.

¿Es algo que un lenguaje de programación explícitamente no debería permitir (como C #, aunque proporciona una solución alternativa) o es una característica de cualquier lenguaje lo suficientemente potente como para dejarla en manos del programador?

Editar: No fui lo suficientemente específico para lo que quise decir con Fallthrough. Uso mucho este tipo:

switch(m_loadAnimSubCt){ case 0: case 1: // Do something break; case 2: case 3: case 4: // Do something break; }

Sin embargo, estoy preocupado por algo como esto.

switch(m_loadAnimSubCt){ case 0: case 1: // Do something but fall through to the other cases // after doing it. case 2: case 3: case 4: // Do something else. break; }

De esta manera, siempre que el caso sea 0, 1, hará todo lo posible en la instrucción switch. Lo he visto por diseño y simplemente no sé si estoy de acuerdo con que las declaraciones de cambio se utilicen de esta manera. Creo que el primer ejemplo de código es muy útil y seguro. El segundo parece un poco peligroso.


¿Has oído hablar del dispositivo de Duff ? Este es un gran ejemplo del uso de interruptor de caída.

Es una función que se puede usar y se puede abusar, como casi todas las características del lenguaje.


Como con cualquier cosa: si se usa con cuidado, puede ser una herramienta elegante.

Sin embargo, creo que los inconvenientes justifican más que NO usarlo, y finalmente no permitirlo más (C #). Entre los problemas están:

  • es fácil "olvidar" un descanso
  • no siempre es obvio para los mantenedores de código QUE una interrupción omitida fue intencional

buen uso de un interruptor / caso fallthrough:

switch (x) { case 1: case 2: case 3: do something break; }

Uso de BAAAAAD de un interruptor / caso fallthrough:

switch (x) { case 1: some code case 2: some more code case 3: even more code break; }

Esto se puede reescribir utilizando construcciones if / else sin pérdida en absoluto, en mi opinión.

Mi última palabra: manténgase alejado de las etiquetas de casos fallidas como en el ejemplo MALO, a menos que esté manteniendo el código heredado donde este estilo se usa y se entiende bien.


El pensamiento de caída debe usarse solo cuando se usa como tabla de salto en un bloque de código. Si hay alguna parte del código con una interrupción incondicional antes de más casos, todos los grupos de casos deben terminar de esa manera. Cualquier otra cosa es "malvada".


En algunos casos, el uso de caídas es un acto de holgazanería por parte del programador; podrían usar una serie de || declaraciones, por ejemplo, pero en su lugar usan una serie de casos de cambio de ''atrapar todo''.

Habiendo dicho eso, he encontrado que son especialmente útiles cuando sé que con el tiempo voy a necesitar las opciones de todos modos (por ejemplo, en una respuesta de menú), pero aún no he implementado todas las opciones. Del mismo modo, si está logrando un fracaso tanto para "a" como para "A", creo que es sustancialmente más limpio utilizar el cambio fallido que una instrucción if compuesta.

Probablemente es una cuestión de estilo y de cómo piensan los programadores, pero generalmente no me gusta eliminar componentes de un lenguaje en nombre de la "seguridad", por lo que me inclino más por C y sus variantes / descendientes que, digamos, Java. Me gusta poder jugar con los punteros y cosas por el estilo, incluso cuando no tengo una "razón" para hacerlo.


Es una espada de dos filos. A veces muy útil, a menudo peligroso.

¿Cuándo es bueno? Cuando quiera 10 cajas, todas procesadas de la misma manera ...

switch (c) { case 1: case 2: ... do some of the work ... /* FALLTHROUGH */ case 17: ... do something ... break; case 5: case 43: ... do something else ... break; }

La única regla que me gusta es que si alguna vez hace algo elegante donde excluye el descanso, necesita un comentario claro / * FALLTHROUGH * / para indicar que era su intención.


Fallthrough es realmente algo útil, dependiendo de lo que estés haciendo. Considere esta forma clara y comprensible de organizar las opciones:

switch ($someoption) { case ''a'': case ''b'': case ''c'': // do something break; case ''d'': case ''e'': // do something else break; }

Imagina hacer esto con if / else. Sería un desastre.


Me encantaría una sintaxis diferente para las interrupciones en los interruptores, algo así como, errr ..

switch(myParam) { case 0 or 1 or 2: // do something; break; case 3 or 4: // do something else; break; }

Nota: Esto ya sería posible con enumeraciones, si declaras todos los casos en tu enumeración usando banderas ¿verdad? Tampoco suena tan mal, los casos podrían (¿debería?) Ser parte de tu enumeración.

Tal vez este sería un buen caso (sin juego de palabras) para una interfaz fluida usando métodos de extensión? Algo así como, errr ...

int value = 10; value.Switch() .Case(() => { /* do something; */ }, new {0, 1, 2}) .Case(() => { /* do something else */ } new {3, 4}) .Default(() => { /* do the default case; */ });

Aunque eso es probablemente aún menos legible: P


No me gusta que las declaraciones de mi switch fallen, es demasiado propenso a errores y difícil de leer. La única excepción es cuando varias declaraciones de case hacen exactamente lo mismo.

Si hay algún código común que quiera usar múltiples ramas de una instrucción switch, lo extracto en una función común separada que se puede llamar en cualquier rama.


Potente y peligroso. El mayor problema con la caída es que no es explícito. Por ejemplo, si te encuentras con código editado con frecuencia que tiene un interruptor con fallas, ¿cómo sabes que es intencional y no es un error?

En cualquier lugar que lo use, me aseguro de que esté debidamente comentado:

switch($var) { case ''first'': // fall-through case ''second'': i++; break; }


Puede depender de lo que considere fallthrough. Estoy bien con este tipo de cosas:

switch (value) { case 0: result = ZERO_DIGIT; break; case 1: case 3: case 5: case 7: case 9: result = ODD_DIGIT; break; case 2: case 4: case 6: case 8: result = EVEN_DIGIT; break; }

Pero si tienes una etiqueta de caja seguida de un código que caiga en otra etiqueta de caja, casi siempre consideraría ese mal. Tal vez mover una clave al código común y llamar desde ambos lugares sería una mejor idea.

Y tenga en cuenta que utilizo la definición de C ++ FAQ de "evil"


Puede ser muy útil algunas veces, pero en general, no es el comportamiento deseado. Fallthrough debe permitirse, pero no implícitamente.

Un ejemplo, para actualizar versiones antiguas de algunos datos:

switch (version) { case 1: // update some stuff case 2: // update more stuff case 3: // update even more stuff case 4: // and so on }


Usar el fall-through como en su primer ejemplo está claramente bien, no lo consideraría un verdadero fracaso.

El segundo ejemplo es peligroso y (si no se lo comenta extensamente) no es obvio. Enseño a mis alumnos a no utilizar tales construcciones A MENOS QUE consideren que vale la pena dedicarle un bloque de comentarios, que describe que esto es un abandono intencional, y por qué esta solución es mejor que las alternativas. Esto desalienta el uso descuidado, pero todavía lo permite en los casos en que se usa con ventaja.

Esto es más o menos equivalente a lo que hicimos en proyectos espaciales cuando alguien quería violar el estándar de codificación: tenían que solicitar la dispensa (y me llamaron para asesorar sobre el fallo).