考虑以下代码:
unsigned global;
while(global);
global
在由 IRQ 调用的函数中进行修改。但是,g++ 删除了“非零”测试并将 while 循环转换为无限循环。
禁用编译器优化可以解决问题,但是 C++ 是否提供了语言结构呢?
将变量声明为volatile
:
volatile unsigned global;
这是告诉编译器global
可以在不同线程中修改的关键字,并且应该为它关闭所有优化。
由于您使用的是 GCC,并且您说使变量volatile
不起作用,您可以欺骗优化器认为循环通过对编译器撒谎来更改变量:
while(global)
asm volatile("" : "+g"(global));
这是一个内联汇编语句,它表示它修改了变量(它作为输入输出操作数传递)。但它是空的,所以很明显它在运行时没有做任何事情。尽管如此,优化器仍然认为它修改了变量 - 程序员是这么说的,而编译器,除非操作数替换(这意味着简单地用另一个文本替换一个文本),并不真正关心内联汇编的主体,也不会做任何事情有趣的事情。
并且因为主体是空的并且约束使用它是最通用的可用的,它应该在 GCC 支持内联汇编的所有平台上可靠地工作。