Considere este código simple:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
Puede ver que gcc
ni clang
optimizar la llamada potencial a g
. En mi opinión, esto es correcto: la máquina abstracta debe suponer que las volatile
variables pueden cambiar en cualquier momento (debido, por ejemplo, a un mapeo de hardware), por lo que el plegado constante de la false
inicialización en la if
comprobación sería incorrecto.
Pero MSVC elimina la llamada por g
completo ( volatile
¡aunque mantiene las lecturas y escrituras en el !). ¿Es este comportamiento compatible con el estándar?
Antecedentes: ocasionalmente uso este tipo de construcción para poder activar / desactivar la salida de depuración sobre la marcha: el compilador siempre debe leer el valor de la memoria, por lo que cambiar esa variable / memoria durante la depuración debería modificar el flujo de control en consecuencia . La salida de MSVC vuelve a leer el valor, pero lo ignora (presumiblemente debido a la eliminación constante del código y / o eliminación del código muerto), lo que, por supuesto, derrota mis intenciones aquí.
Ediciones:
volatile
Aquí se analiza la eliminación de las lecturas y escrituras : ¿está permitido que un compilador optimice una variable volátil local? (¡Gracias Nathan!). Creo que el estándar es muy claro que esas lecturas y escrituras deben suceder. Pero esa discusión no cubre si es legal que el compilador tome los resultados de esas lecturas por sentado y optimice en función de eso. Supongo que esto está sub / no especificado en el estándar, pero sería feliz si alguien demostrara que estoy equivocado.Por supuesto, puedo hacer
x
una variable no local para evitar el problema. Esta pregunta es más por curiosidad.