我想编写一个触发页面写入时写入的函数,而不必修改该页面中的任何值。一个简单的实现:
void trigger_cow(char* addr){
*addr = *addr;
}
不起作用,因为GCC会优化生产线。如果我使用volatile,
void trigger_cow(char* addr){
volatile char* vaddr = (volatile char*) addr;
*vaddr = *vaddr;
}
然后这在-O3下工作。
这种“黑客”会在其他编译器或优化设置下工作吗?
我所见过的大多数网站中的volatile的描述似乎并没有描述当你写一个易失性指针时会发生什么,只有当你从一个读取时会发生什么。谢谢!
答案 0 :(得分:4)
这正是volatile
所做的......它强制读取和写入每次访问变量时都会发生一次,并且与读取和写入的顺序相同(它们不能出现在程序中)重新排序)。
请注意,处理器仍然可以重新排序读取和写入 * ,因此volatile
对于多线程编程并不是特别有用。
* 除了安腾ABI,但这是独一无二的。
答案 1 :(得分:2)
正式地,对volatile
变量的任何访问都构成了程序的可观察行为。它不能被优化,也不能对可观察行为的其他元素进行重新排序。
C ++程序中的优化是在“仿佛”规则下执行的,只要它不改变程序的可观察行为,它基本上赋予编译器执行任何操作的权限。
答案 2 :(得分:1)
标准(§1.9/ 8)要求:
符合实施的最低要求是:
- 严格按照抽象机的规则评估对volatile对象的访问。
“访问”被定义为读取或写入,所以是的,您的*vaddr = *vaddr;
必须从*vaddr
读取值,然后将相同的值写回*vaddr
。