在C++03标准中,可观察行为(1.9/6)包括读取和写入易失性数据。现在我有了下面的代码:
int main()
{
const volatile int value = 0;
if( value ) {
}
return 0;
}它正式初始化一个易失性变量,然后读取它。Visual C++ 10通过将dword推入堆栈来发出在堆栈上腾出空间的机器码,然后将零写入堆栈位置,然后读取该位置。
对我来说,这是没有意义的-没有其他代码或硬件可能知道局部变量的位置(因为它在自动存储中),所以期望变量可能已经被任何其他方读/写是不合理的,所以在这种情况下它可以被消除。
是否允许消除此变量的访问权限?是否可以观察到访问易失性本地地址的其他任何一方都不知道的行为?
发布于 2011-09-26 17:32:35
线程的整个堆栈可能位于一个受保护的内存页上,有一个处理程序记录所有读取和写入(当然,并允许它们完成)。
然而,我不认为MSVC真的关心内存访问是否或如何被检测到。它将volatile理解为,在其他事情中,“不必费心对此对象应用优化”。所以它不需要。它不需要说得通,因为MSVC对加速这种volatile的使用不感兴趣。
因为它依赖于实现,是否以及如何实际观察到可观察的行为,我认为您是对的,如果一个实现知道,由于硬件的细节,访问不可能被检测到,那么它可能会“作弊”。没有物理上可检测效果的可观察行为可以跳过:无论标准怎么说,检测不符合行为的方法仅限于物理上可能的。
如果一个实现在森林中不符合标准,并且没有人注意到,它会发出声音吗?差不多吧。
发布于 2011-09-26 17:35:52
这就是声明变量volatile的全部意义:您告诉实现该变量可能会更改或被实现本身未知的方式读取,并且实现应该避免执行可能影响此类访问的优化。
当一个变量同时声明为volatile和const时,您的程序不能更改它,但仍然可以从外部更改它。这意味着不仅变量本身,而且它的所有读操作都不能被优化。
发布于 2011-09-26 18:08:20
任何其他代码或硬件都不可能知道
您可以查看程序集(您刚才已经这样做了!),找出变量的地址,并在调用期间将其映射到某些硬件。volatile意味着实现也必须考虑到这些事情。
https://stackoverflow.com/questions/7553017
复制相似问题