为什么ACCESS_ONCE如此复杂?

时间:2014-03-31 09:36:57

标签: c linux-kernel

Linux ACCESS_ONCE宏定义如下:

#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))

我明白这是做什么的,但想知道它为何如此复杂?我的理解是它做了以下事情:

  1. 获取关注变量的地址(创建临时指针)
  2. 将其转换为相同类型的易失性指针
  3. 取消引用该指针
  4. 任何想法为什么不能以更简单的方式实施,比如说:

     #define ACCESS_ONCE(x) ((volatile typeof(x))(x))
    

3 个答案:

答案 0 :(得分:10)

ACCESS_ONCE宏用于从已知(或怀疑)为易失性存储位置检索值但未按类型输入的情况。目的是检索存储位置的当前值,以便打败优化编译器,否则优化编译器可能会将值缓存在寄存器中,甚至根本不提供存储位置。

所写的构造通过声明指向该位置的适当类型指针,间接地将“volatile”应用于存储位置。根据C标准,这要求object be evaluated strictly according to the rules of the abstract machine

您提议的修改不会将volatile应用于存储位置,因此无法实现此目的。价值检索可以进行优化。

顺便说一句,我认为这是所述目的的简明模型。我保留complex比这更糟糕的事情。

答案 1 :(得分:0)

对“简单”变量进行volatile转换基本上没用 - 它不会改变底层访问语义,所以这不是你想要的。

答案 2 :(得分:-1)

这个 link 解释了为什么将变量变为volatile没有影响的深层原因。

  

将值转换为限定类型无效;资格   (volatile,比如说)因为它已经发生,对访问没有任何影响   案件之前。如果有必要访问非易失性对象   使用volatile语义,技术是转换地址   反对适当的指向限定类型​​的指针,然后取消引用   指针。