Estoy tomando un curso intermedio de estructuras de datos como requisito previo para ingresar al programa CS MS en una universidad de la que todos en América han oído hablar. Me llamó la atención una línea de código escrita en clase:
if (a > 33 | b++ < 54) {...}
Esto no pasaría una revisión de código en mi lugar de trabajo. Si escribió un código como este en una entrevista, este sería un ataque significativo contra usted. (Además de ser un condicional con efectos secundarios, es inteligente a expensas de la claridad).
De hecho, nunca he visto un condicional con efectos secundarios, y Google tampoco aparece mucho. Otro estudiante se quedó después de clase para preguntar sobre eso también, así que no soy el único que pensó que esto era extraño. Pero el profesor insistió bastante en que este era un código aceptable y que escribiría algo así en el trabajo. (Su trabajo de FT es como SWE principal en una compañía de la que todos han oído hablar).
No puedo imaginar un mundo en el que esta línea de código sea alguna vez aceptable, y mucho menos deseable. ¿Me equivoco? ¿Esta bien? ¿Qué pasa con el caso más general: condicionales con efectos secundarios? ¿Alguna vez están bien?
fuente
Respuestas:
Hay un efecto secundario semi-condicional que puedo pensar que está bien:
while(iter.MoveNext())
Dicho esto, creo que esto cae principalmente en la categoría " nunca es un calificador realmente grande". Puedo pensar en algunos casos raros en los que he visto que es aceptable, pero en general esto es vil y debe evitarse.
Tampoco puedo pensar en un escenario donde esa línea particular sería aceptable, pero tampoco puedo pensar en un escenario donde esa línea particular sería útil , por lo que es difícil imaginar el contexto en el que se encuentra.
fuente
while(v = *p++)
escaneos de estilo C / C ++ a través de una matriz terminada en cero (por ejemplo, cadena C) son bastante comunes y ampliamente aceptados.while(c = input.read() != '\n')
son razonablemente idiomáticos.En mi mundo, una lectura de memoria puede considerarse un efecto secundario (p. Ej., Memoria asignada IO).
Ahora, considere lo siguiente:
Y comparar con:
¿Evitar el efecto secundario (la lectura) en la condición ayudó a la legibilidad? ¿O simplemente duplicó el código y agregó desorden?
No está bien que una condición tenga efectos secundarios (si eso hace que el código sea menos legible) y también está bien que una condición tenga efectos secundarios (si eso hace que el código sea más legible). El factor clave es la "legibilidad". Todo lo demás son reglas creadas por tontos en un intento equivocado de mejorar la legibilidad (mientras que a menudo tienen el efecto contrario).
fuente
Como siempre con tales preguntas, esto es una cuestión de grado. Si hubiera pruebas inequívocas de que cualquier efecto secundario dentro de una
if
expresión siempre conducía a un código peor, entonces no sería legal crear esas expresiones. Los diseñadores de lenguajes pueden ser ideosincrática, los seres humanos falibles, pero no lo son que estúpida.Dicho esto, ¿cuáles son ejemplos de efectos secundarios justificados dentro de un
if
? Por ejemplo, suponga que tiene la obligación legal de registrar todo y cualquier acceso a la propiedadP
de una entidadE
para fines de auditoría. (Imagine que está trabajando en una planta de enriquecimiento de uranio, y existen controles legales muy estrictos sobre lo que su código tiene permitido hacer y cómo se supone que debe hacerlo). Luego, cualquieraif
que verifique esa propiedad causará el efecto secundario de El registro de auditoría se está extendiendo.Esa es una preocupación transversal bastante clara, no afecta su razonamiento sobre el estado del programa (mucho), y puede implementarlo para que sea completamente invisible y no distraiga cuando revisa la línea con el
if
(oculto lejos en el accesor, o incluso mejor a través de AOP). Yo diría que es un caso bastante claro de un efecto secundario que no es una preocupación. Se pueden imaginar situaciones similares cuando solo desea contar las ejecuciones de sucursales con fines de creación de perfiles, etc.Cuanto más desaparezcan estas circunstancias atenuantes, más extraña será la construcción. Si un tipo de bucle particular (por ejemplo,
if((c = getc()) == 'x') { quit(); }
es bien conocido y aceptado por la comunidad lingüística, entonces es mucho menos problemático que cuando lo inventa espontáneamente, etc. Su línea de ejemplo no cumple con ese estándar, pero podría imaginar mucho, mucho más horribles que ni siquiera escribiré, son tan horribles.fuente
Aunque es un código realmente maloliente, tiene la ventaja de ser más simple (y quizás más rápido si no tiene un buen compilador de optimización) que el equivalente
if (a > 33 | b < 54) {b++; ...} else b++;
pero, por supuesto, es posible optimizarlo de la siguiente manera (¡pero cuidado! ¡Este tiene un comportamiento diferente en caso de desbordamiento!):
b++; if (a > 33 | b < 53) {...}
fuente