Pregunta

Un cliente recientemente realizó el análisis estático del código base C de mi empleador y nos dio los resultados. Entre los parches útil fue la solicitud de cambio de la famosa do { ... } while(0) macro para do { ... } while(0,0). Entiendo lo que su parche está haciendo (usando el operador de secuencia a retorno evaluar el valor del segundo "0", por lo que el efecto es el mismo), pero no está claro por qué habían favorecen la segunda formar sobre la primera forma.

¿Hay una razón legítima por la que se debe preferir la segunda forma de la macro, o está siendo excesivamente pedante análisis estático de nuestros clientes?

¿Fue útil?

Solución

Bueno, voy a ir por respuesta:

  

¿Hay una razón legítima por la que se debe preferir la segunda forma de la macro ...?

No. No hay ninguna razón legítima. Ambos siempre se evalúan como falso, y cualquier compilador decente probablemente gire la segunda a la primera en el montaje de todos modos. Si había alguna razón para que sea válida en algunos casos, C ha estado presentes por mucho tiempo suficiente para que la razón de ser descubierto por mayores gurús que yo.

Si te gusta su código haciendo ojos de búho-Y a ti, utilizar while(0,0). De lo contrario, utilizar lo que usa el resto del mundo de programación C y di herramienta de análisis estático de su cliente a empujarlo.

Otros consejos

Sólo una conjetura en cuanto a por qué podrían sugerir el uso

do { ... } while(0,0)

sobre

do { ... } while(0)

A pesar de que no hay ninguna diferencia de comportamiento y debería haber ninguna diferencia en el costo de tiempo de ejecución entre los dos.

Mi conjetura es que la herramienta de análisis estático se queja por el bucle while siendo controlado por una constante en el caso más simple, y no lo hace cuando se utiliza 0,0. La sugerencia de que el cliente es, probablemente, sólo para que no consiguen un montón de falsos positivos de la herramienta.

Por ejemplo, yo de vez en cuando vienen a través de situaciones en las que quieren tener una sentencia condicional controlada por una constante, pero el compilador se quejará con una advertencia acerca de una expresión condicional evaluar a una constante. Entonces tengo que saltar a través de algunos aros para conseguir el compilador para dejar de quejarse (ya que no me gusta tener advertencias falsas).

sugerencia de su cliente es uno de los aros que he usado para calmar la advertencia de que, aunque en mi caso no estaba controlando un bucle while, fue para hacer frente a una "siempre es incapaz de" afirmación. De vez en cuando, voy a tener un área de código que nunca se debe ejecutar (tal vez el caso por defecto de un interruptor). En esa situación, que podría tener una afirmación de que siempre falla con algún mensaje:

assert( !"We should have never gotten here, dammit...");

Pero, al menos un compilador utilizo emite una advertencia acerca de la expresión evaluando siempre a falso. Sin embargo, si la cambio a:

assert( ("We should have never gotten here, dammit...", 0));

La advertencia desaparece, y todo el mundo es feliz. Supongo que la herramienta de análisis estático, incluso de su cliente sería, también. Tenga en cuenta que por lo general oculto ese poco de aro saltar detrás de un macro como:

#define ASSERT_FAIL( x) assert( ((x), 0))

Puede ser que sea agradable ser capaz de decirle al proveedor de herramientas para solucionar el problema, pero puede haber casos legítimos en el que realmente no quieren diagnosticar un bucle de ser controlado por una expresión booleana constante. Por no mencionar el hecho de que, incluso si se convence a un proveedor de herramientas para hacer un cambio de este tipo, que no te ayuda para el próximo año o así que se podrían adoptar para conseguir realmente una solución.

Uso while(0,0) impide Microsoft compilador desde la generación de una advertencia sobre una condición que es una constante (Advertencia C4127).

Cuando se activa esta advertencia (por ejemplo, con / W4 o / Wall), que puede ser cerrado en una base de caso por caso con este pequeño truco agradable ( ver este otro hilo ).

EDIT: Desde Visual Studio 2017 15.3, while(0) no emite advertencias más (cf. Los condicionales constantes ). Usted puede deshacerse de su (0,0)!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top