考虑以下代码:
int square(volatile int *p)
{
return *p * *p;
}
现在, volatile
关键字表示内存位置中的值可以以编译器未知的方式更改或具有其他未知的副作用(例如通过信号中断、硬件寄存器或内存映射 I/ O) 即使程序代码中没有任何内容修改内容。
那么当我们将指针声明为 volatile 时究竟会发生什么?
上面提到的代码是否总是有效,或者与此有什么不同:
int square(volatile int *p)
{
int a = *p;
int b = *p
return a*b;
}
我们可以最终乘以不同的数字,因为指针是易变的吗?
或者有更好的方法吗?
原文由 vishal 发布,翻译遵循 CC BY-SA 4.0 许可协议
绝对地;任何类型,不包括函数和引用,都可能是
volatile
。请注意,一个 volatile 指针被声明为
T *volatile
,而不是volatile T*
,而是声明一个 指向-volatile 的指针。易失性指针意味着指针值,即它的地址而不是指向的值,可能具有编译器在访问时不可见的副作用;因此,这些访问可能不会考虑源自“as-if 规则”的优化。
编译器不能假设读取
*p
获取相同的值,因此不允许将其值缓存在变量中。正如您所说,结果可能会有所不同,而不是*p
的平方。具体示例:假设您有两个数组
int
s和指向其中之一的指针
对尖元素进行一些操作
这里
p
必须在每次迭代时读取volatile
因为,由于外部事件,它可能实际上指向a2
。