指向非易失性数据的易失性指针

时间:2016-08-04 23:17:39

标签: c++ c pointers volatile non-volatile

假设我有以下声明:

int* volatile x;

我相信这定义了一个易失性指针“普通”变量。

对我而言,这可能意味着两件事之一:

首先猜猜

指针可以更改,但数字不会发生变化,恕不另行通知。这意味着一些其他线程(编译器不知道)可以更改指针,但如果旧指针指向“12”则指向新指针(指针的新值,因为线程更改它) )会指向另一个“12”。

对我而言,这似乎毫无用处,我会假设这不是真正的操作。

第二次猜测

指针可以更改,因此如果指针发生更改,编译器必须在使用之前重新加载指针中的值。但是如果它确认指针没有改变(带有附加的检查),那么它可以假设它指向的值也保持不变。

所以我的问题是:

声明指向非易失性数据的易失性指针实际上做了什么?

2 个答案:

答案 0 :(得分:2)

int *volatile x;声明一个指向非易失性int的易失性指针。

每当访问指针时,volatile限定符都保证从内存中重新读取其值(指针的值)。

由于指向int是非易失性的,因此允许编译器在指针的当前值指向的地址处重用先前缓存的值。从技术上讲,无论指针是否已更改,都允许这样做,只要存在最初从当前地址检索到的缓存值。

<小时/> [编辑]为了解决@ DavidSchwartz的评论,我应该注意到“从内存中重读”是一个(不是迂回精确,但AFAIK常用)的简写,“就好像它是 - 从抽象机器中的内存中读取“。

例如,C11草案N1570 6.7.3 / 7说:

  

具有volatile限定类型的对象可能会以实现未知的方式进行修改,或者具有其他未知的副作用。因此,任何涉及这种对象的表达都应严格按照抽象机的规则进行评估,如5.1.2.3所述。此外,在每个序列点,最后存储在对象中的值应与抽象机器规定的值一致,除非由前面提到的未知因素修改(134)。什么构成对具有volatile限定类型的对象的访问是实现定义的。

相同的草案有6.5.16 / 3(作业运营商)的脚注:

  

允许实现读取对象以确定值但不是必需的,即使对象具有volatile-quali fi ed类型

所以最后volatile没有要求物理内存读取,但是兼容实现的可观察行为必须,就好像一样

答案 1 :(得分:-2)

volatile表示指针的值(即它指向的存储位置)可以改变;因此,编译器必须确保各种高速缓存对于该指针具有相同的值,或者为每次读取从内存加载指针,并在每次写入时将其写入内存。

然而,volatile对指向的值没有任何说明。所以它可以改变,并且在不同的线程中可能有不同的值。