我知道何时需要指向易失性值的指针(例如,读取内存映射外设)。但是什么时候你需要指针本身是易失性的?>
答案 0 :(得分:3)
要详细说明我的评论,首先要记住volatile
的含义是非常重要的:它是编译器的一个信号,即声明的变量可能会通过编译器无法看到的机制以意外的方式发生变化或控制和读取和写入可能有副作用。因此,编译器通常每次都会从主内存重新加载变量的值,而不是使用缓存值,并且不会执行删除,重新排序或删除对此类volatile
变量的读取或写入的优化。
通常情况下,大多数用户空间代码都不必担心这种情况,并且volatile
的合法使用距离很少。
您的问题还引用了该语言的一个微妙且不为人所知的特性:能够将指针本身声明为volatile
(或const
)而非事物它指向。您可以使用以下语法执行此操作:
int *volatile p = 0x74;
这声明了volatile
指针指向内存位置int
的{{1}}。与此对比:
0x74
声明指向地址volatile int *p = 0x74;
volatile int
的指针
这两者之间的区别在于您访问0x74
时会发生什么。我们只会关注阅读案例:
对于每次读取访问的指针p
,编译器将转到内存位置volatile int
并读取(可能使用特殊CPU指令)该位置的0x74
值 - 代码不会缓存该值(但可能是硬件)。
如果int
指针指向volatile
,编译器将在每次访问时重新加载指针的值,然后继续阅读int
在那个地址。该地址不会缓存在代码中(但同样,它可以由硬件缓存)。
与写作类似。
同样,请务必记住int
限制编译器(例如,它无法优化写入或读取),因为volatile
变量上的任何操作都可能具有副作用对编译器不可见。这种副作用的一个例子可能是产生中断,闪烁LED,写入审计记录或更改寄存器的值。