如何防止g ++优化由可由IRQ更改的变量控制的循环?

时间:2012-02-29 08:37:25

标签: c++ gcc g++ irq

考虑以下代码:

unsigned global;
while(global);

global在由IRQ调用的函数中被修改。但是,g ++删除了" is-not-zero"测试并将while循环转换为无限循环。

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

3 个答案:

答案 0 :(得分:17)

将变量声明为volatile

volatile unsigned global;

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

答案 1 :(得分:8)

由于您正在使用GCC并且您说使变量volatile不起作用,您可以欺骗优化器认为循环通过向编译器说明来更改变量:

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

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

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

答案 2 :(得分:2)

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

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

有关详细信息,请参阅GCC Function Attributes页面。