Mi pregunta es sobre la línea que he mencionado en el tema y que puedo ver en muchos lugares dentro del código de producción.
El código general se ve así:
if (0) {
// Empty braces
} else if (some_fn_call()) {
// actual code
} else if (some_other_fn_call()) {
// another actual code
...
} else {
// default case
}
Las otras ramas son irrelevantes para mi pregunta. Me pregunto cuál es el significado de poner if (0)
aquí. Las llaves están vacías, así que no creo que deba comentar algún bloque de código. ¿Obliga al compilador a hacer alguna optimización o sus intenciones son diferentes?
He intentado buscar este caso explícito aquí en SO y en Internet, pero sin éxito. Hay preguntas similares sobre JavaScript, pero no C. Hay otra pregunta, ¿qué sucede cuando se asigna un cero en una condición `if`? , pero analiza la asignación cero a una variable, no el uso 'if (0)' en sí mismo.
c
if-statement
Zzaponka
fuente
fuente
Respuestas:
A veces uso esto para la simetría para poder mover el otro
else if{
libremente con mi editor sin tener que preocuparme por el primeroif
.Semánticamente el
parte no hace nada y puede contar con optimizadores para eliminarlo.
fuente
if else
prefijo común a todas las rutas de código significativas alinea las condiciones muy bien y facilita el escaneo. (Sin embargo, eso es subjetivo y dependería mucho de lo que realmente está dentro de las condiciones y los bloques de código).if (0) {..}
presente ningún problema de legibilidad / legibilidad. Debería ser obvio para cualquiera que sepa un poco de C. Eso no es un problema. El problema es la pregunta de seguimiento después de leerlo: "¿Para qué demonios es entonces?" A menos que sea para fines de depuración / temporales (es decir, la intención es "habilitar" eseif
bloqueo más adelante), recomendaría eliminarlo por completo. Básicamente, "leer" dicho código probablemente causaría una "pausa" innecesaria para el lector sin una buena razón. Y esa es una buena razón para eliminarlo.else if
por el editor sin preocuparse" porque las condiciones pueden no ser mutuamente excluyentes, en cuyo caso el orden es importante. Personalmente, solo usaríaif
y realizaría un retorno temprano , extrayendo la cadena lógica a una función separada si fuera necesario.Esto puede ser útil si hay
#if
declaraciones, alaetc.
En este caso, cualquiera (y todas) de las pruebas se pueden
#if
eliminar y el código se compilará correctamente. Casi todos los compiladores eliminarán laif (0) {}
pieza. Un generador automático simple podría generar un código como este, ya que es un poco más fácil de codificar: no tiene que considerar el primer bloque habilitado por separado.fuente
if
/else if
no se usa tanto como un árbol de decisión, sino más bien como una construcción de "actuar según la primera condición coincidente", donde la condición que tiene la más alta prioridad no es particularmente "especial". Si bien no lo había vistoif(0)
como una forma de permitir que todas las ramas reales tengan una sintaxis consistente, me gusta la sintaxis consistente que facilita.else if
línea en dos y coloque el protector del preprocesador en el medio.if (0)
rama y volvería a formatear el resto de modo queelse
esté en su propia línea, rodeada por un guardia a lo largo de las líneas de#if TEST1_ENABLED && TEST2_ENABLED
.He visto un patrón similar usado en el código generado. Por ejemplo, en SQL, he visto que las bibliotecas emiten la siguiente
where
cláusula.Presumiblemente, esto hace que sea más fácil agregar otros criterios, ya que todos los criterios adicionales pueden anteponerse en
and
lugar de una verificación adicional para ver si es el primer criterio o no.fuente
1=1
también es "útil" porque siempre puede agregar elwhere
frente, incondicionalmente. De lo contrario, deberá verificar si está vacío y, de ser así, evitar generar lawhere
cláusula.1=1
deWHERE
, por lo que no tiene un impacto en el rendimiento.Tal como está escrito, el
if (0) {}
cláusula se compila en nada.Sospecho que la función de la cláusula en la parte superior de esta escalera es proporcionar un lugar fácil para deshabilitar temporalmente todas las demás funciones a la vez (para fines de depuración o comparación) cambiando el
0
a a1
otrue
.fuente
No estoy seguro de ninguna optimización, pero mis dos centavos:
Esto sucedió debido a alguna modificación del código, donde se eliminó una condición primaria (la llamada a la función en el
if
bloque inicial , digamos), pero los desarrolladores / mantenedoresif-else
bloqueasí que en lugar de eliminar el
if
bloque asociado , simplemente cambiaron la condiciónif(0)
y continuaron.fuente
if(0)
disminuye también la cobertura de sucursales?Es la putrefacción del código.
En algún momento que "si" hizo algo útil, la situación cambió, tal vez se eliminó la variable que se está evaluando.
La persona que estaba arreglando / cambiando el sistema hizo lo menos posible para afectar la lógica del sistema por lo que se aseguró de que el código se volviera a compilar. Entonces deja un "si (0)" porque es rápido y fácil y no está totalmente seguro de que eso es lo que quiere hacer. Hace que el sistema funcione y no regresa para arreglarlo por completo.
Luego aparece el siguiente desarrollador y piensa que se hizo deliberadamente y solo comenta esa parte del código (ya que de todos modos no se está evaluando), luego la próxima vez que se toque el código, esos comentarios se eliminarán.
fuente
Una posibilidad aún no mencionada: la
if (0) {
línea podría ser un lugar conveniente para un punto de interrupción.La depuración a menudo se realiza en código no optimizado, por lo que la prueba siempre falsa estará presente y podrá tener un punto de interrupción establecido. Cuando se compila para la producción, la línea de código se optimizará. La línea aparentemente inútil brinda funcionalidad para el desarrollo y las versiones de prueba sin afectar las versiones de lanzamiento.
Hay otras buenas sugerencias anteriores también; La única forma de saber realmente cuál es el propósito es localizar al autor y preguntar. Su sistema de control de código fuente podría ayudar con eso. (Busque la
blame
funcionalidad de tipo).fuente
He visto bloques de código no accesibles en JavaScript previamente expandido que se han generado utilizando un lenguaje de plantillas.
Por ejemplo, el código que está leyendo podría haberse pegado desde un servidor que evaluó previamente la primera condición que en ese momento dependía de una variable solo disponible en el lado del servidor.
que una vez compilaron previamente hences:
¡Espero que esto te ayude a relativizar la potencial actividad de teclado bajo de la era de los codificadores de reciclaje profesional por la cual manifesté entusiasmo!
fuente
Esa construcción también se puede usar en C para implementar programación genérica con seguridad de tipo, basándose en el hecho de que el compilador sigue comprobando el código inalcanzable:
fuente
Creo que es solo un mal código. Al escribir un ejemplo rápido en Compiler Explorer, vemos que tanto en gcc como en clang no se genera código para el
if (0)
bloque, incluso con optimizaciones completamente deshabilitadas:https://godbolt.org/z/PETIks
Jugar con la eliminación de las
if (0)
causas no causa cambios en el código generado, por lo que concluyo que esto no es una optimización.Es posible que haya algo en el
if
bloque superior que luego se eliminó. En resumen, parece que eliminarlo podría generar exactamente el mismo código, así que siéntase libre de hacerlo.fuente
Como se ha dicho, el cero se evalúa como falso y es probable que el compilador optimice la rama.
También he visto esto antes en el código donde se agregó una nueva función y se necesitaba un interruptor de apagado (si algo sale mal con la función, simplemente puede desactivarlo), y algún tiempo después, cuando se quitó el interruptor de apagado el programador tampoco eliminó la rama, por ejemplo
convirtió
fuente
Ayuda a depurar este bloque simplemente colocando el bloque 1. Esto deshabilita toda la funcionalidad del bloque if else. Y también podemos expandir el bloque if else.
fuente
fuente
La respuesta de @ PSkocik está bien, pero agrego mis dos centavos. No estoy seguro si debo hacer esto como un comentario, o como una respuesta; elegir este último, porque en mi humilde opinión vale la pena ver a otros, mientras que los comentarios son con frecuencia invisibles.
No solo uso ocasionalmente
Pero también ocasionalmente
o
para condiciones complicadas Por las mismas razones: más fácil de editar, #ifdef, etc.
Para el caso, en Perl haré
Comparo el
if(0)
código con lispque, lo has adivinado, puedo sangrar como
A veces he tratado de imaginar cómo podría ser una sintaxis más legible para esto.
Quizás
inspirado por Dikstra [ https://en.wikipedia.org/wiki/Guarded_Command_Language#Selection:_if[[Guarded Command Language].
Pero esta sintaxis implica que las condiciones se evalúan en paralelo, mientras que
if...else-if
implica una evaluación secuencial y priorizada de las condiciones.Comencé a hacer este tipo de cosas cuando escribía programas que generaban otros programas, donde es especialmente conveniente.
Mientras estamos en eso, cuando escribo RTL usando el viejo iHDL de Intel, he codificado cosas como
donde
FORC..DOC..ENDC
es una construcción de bucle de preprocesador de macro, que se expande aEste era un código de asignación única, no imperativo, por lo que no se permitía establecer una variable de estado, si necesitaba hacer cosas como encontrar el primer bit establecido.
Ahora que lo pienso, este puede haber sido el primer lugar en el que me encontré con tales construcciones.
Por cierto, las objeciones que algunos tenían al estilo if (0), que las condiciones else-if dependen secuencialmente y no se pueden reordenar arbitrariamente, no se aplican a la lógica AND y OR y XOR en RTL, pero se aplican a short- circuito && y ||.
fuente
He visto esto usado para manejar errores, por ejemplo
Esto puede ser útil cuando goto se usa para administrar errores, las declaraciones se ejecutan solo cuando ocurre un error. Vi esto en un código C muy antiguo (donde los argumentos de la función están escritos fuera de '()'), no creo que nadie siga esto ahora.
fuente
Lo he visto varias veces, creo que la razón más probable es que estaba evaluando algo en una versión / rama más antigua / diferente del código, o posiblemente para la depuración, y cambiarlo a
if(0)
es una forma algo perezosa de eliminar lo que estaba allí .fuente