c++ - mac - g++ ubuntu
¿Cómo evitar que g++ optimice un bucle controlado por una variable que puede cambiarse mediante una IRQ? (3)
Declara la variable como volatile
:
volatile unsigned global;
Esta es la palabra clave que le dice al compilador que se puede modificar global
en diferentes subprocesos y que todas las optimizaciones deben desactivarse para ello.
Considere el siguiente código:
unsigned global;
while(global);
global
se modifica en una función que es invocada por un IRQ. Sin embargo, g ++ elimina la prueba "no es cero" y convierte el bucle while en un bucle sin fin.
Deshabilitar la optimización del compilador resuelve el problema, pero ¿C ++ ofrece una construcción de lenguaje para él?
Puede usar los atributos GCC en la declaración de función para deshabilitar la optimización por función:
void myfunc() __attribute__((optimize(0)));
Consulte la página Atributos de la función GCC para obtener más información.
Ya que estás usando GCC y dices que hacer que la variable sea volatile
no funciona, puedes hacer que el optimizador piense que el bucle cambia la variable mintiendo al compilador:
while(global)
asm volatile("" : "+g"(global));
Esta es una declaración de ensamblaje en línea que dice que modifica la variable (se pasa como un operando de entrada-salida). Pero está vacío, así que obviamente no hace nada en tiempo de ejecución. Aún así, el optimizador cree que modifica la variable; los programadores lo dijeron, y el compilador, a excepción de la sustitución de operandos (lo que significa simplemente reemplazar un texto por otro), no se preocupa realmente por el cuerpo del ensamblaje en línea y no hará nada. Cosas graciosas para ello.
Y como el cuerpo está vacío y la restricción es la más genérica disponible, debería funcionar de manera confiable en todas las plataformas en las que GCC admite el ensamblaje en línea.