“volatile”是否足以阻止C ++编译器优化静默写入?

时间:2013-11-19 19:29:12

标签: c++ volatile

我想编写一个触发页面写入时写入的函数,而不必修改该页面中的任何值。一个简单的实现:

void trigger_cow(char* addr){
    *addr = *addr;
}

不起作用,因为GCC会优化生产线。如果我使用volatile,

void trigger_cow(char* addr){
    volatile char* vaddr = (volatile char*) addr;
    *vaddr = *vaddr;
}

然后这在-O3下工作。

这种“黑客”会在其他编译器或优化设置下工作吗?

我所见过的大多数网站中的volatile的描述似乎并没有描述当你写一个易失性指针时会发生什么,只有当你从一个读取时会发生什么。谢谢!

3 个答案:

答案 0 :(得分:4)

这正是volatile所做的......它强制读取和写入每次访问变量时都会发生一次,并且与读取和写入的顺序相同(它们不能出现在程序中)重新排序)。

请注意,处理器仍然可以重新排序读取和写入 * ,因此volatile对于多线程编程并不是特别有用。

* 除了安腾ABI,但这是独一无二的。

答案 1 :(得分:2)

正式地,对volatile变量的任何访问都构成了程序的可观察行为。它不能被优化,也不能对可观察行为的其他元素进行重新排序。

C ++程序中的优化是在“仿佛”规则下执行的,只要它不改变程序的可观察行为,它基本上赋予编译器执行任何操作的权限。

答案 2 :(得分:1)

标准(§1.9/ 8)要求:

  

符合实施的最低要求是:
   - 严格按照抽象机的规则评估对volatile对象的访问。

“访问”被定义为读取或写入,所以是的,您的*vaddr = *vaddr;必须从*vaddr读取值,然后将相同的值写回*vaddr

相关问题