22

考虑以下代码:

unsigned global;
while(global);

global在由 IRQ 调用的函数中进行修改。但是,g++ 删除了“非零”测试并将 while 循环转换为无限循环。

禁用编译器优化可以解决问题,但是 C++ 是否提供了语言结构呢?

4

3 回答 3

17

将变量声明为volatile

volatile unsigned global;

这是告诉编译器global可以在不同线程中修改的关键字,并且应该为它关闭所有优化。

于 2012-02-29T08:38:42.433 回答
10

由于您使用的是 GCC,并且您说使变量volatile不起作用,您可以欺骗优化器认为循环通过对编译器撒谎来更改变量:

while(global)
  asm volatile("" : "+g"(global));

这是一个内联汇编语句,它表示它修改了变量(它作为输入输出操作数传递)。但它是空的,所以很明显它在运行时没有做任何事情。尽管如此,优化器仍然认为它修改了变量 - 程序员是这么说的,而编译器,除非操作数替换(这意味着简单地用另一个文本替换一个文本),并不真正关心内联汇编的主体,也不会做任何事情有趣的事情。

并且因为主体是空的并且约束使用它是最通用的可用的,它应该在 GCC 支持内联汇编的所有平台上可靠地工作。

于 2012-02-29T15:02:14.687 回答
3

您可以在函数声明中使用 GCC 属性来禁用基于每个函数的优化:

void myfunc() __attribute__((optimize(0)));

有关更多信息,请参阅GCC 函数属性页面。

于 2012-02-29T09:36:29.990 回答