为什么这个函数会将一个int参数转换为一个易失性指针并立即取消引用它?

时间:2013-07-02 12:42:17

标签: c

我只想知道以下功能在做什么

static int myfunc(int val)
{
    return *(volatile int *)val;
}

4 个答案:

答案 0 :(得分:24)

如果 val 是将指针传递给此函数时的指针,则会确保读取此指针指向的值并将其返回给调用者。

我怀疑这可能是嵌入式设备的一个技巧,有时在地址读取值的操作会对硬件产生一些影响。
例如,从硬件FIFO读取将弹出FIFO的读取值。

将指针标记为 volatile ,如果检测到未使用该值,则编译器优化读取。

示例:

#define FIFO_ADDRESS 0x800050

static int myfunc(int val)
{
    return *(volatile int *)val; // the address *will* be read
}

static int bad( int val )
{
    return *(int*)val; // might be optimized to nop()  
                       // by the compiler if the value 
                       // is not used by the caller
}

int main(){
   bad( FIFO_ADDRESS );    // could be NOP since return value is not used

   myfunc( FIFO_ADDRESS ); // *WILL* perform a READ operation on the FIFO, 
                           // even though the result is not used, because 
                           // of the volatile keyword

}

请注意,我会采用不同的方式,可能是一个名字很明确的宏:

#define FORCE_INT_PTR_READ( address ) *(volatile int *)address 

您能否举例说明您的情况?

答案 1 :(得分:5)

它似乎试图混淆优化器(可能还有用户)。它取一个整数,将其视为指向整数的指针,并取消引用它。 'volatile'确保优化器将在该点为该解除引用生成代码,并且不会让优化器省略从内存中获取的内容。这通常用于访问存储器映射的硬件寄存器,

答案 2 :(得分:2)

它执行以下操作:

  • 将有符号整数传递给函数。
  • 将有符号整数的内容转换为指针。这没有意义,因为指针无法签名。形式上,这也不是明确定义的行为,任何事情都可能发生。
  • volatile关键字表示val的内容应等于物理硬件地址。从这些地址读取时,volatile关键字是必要的,因为硬件寄存器的内容可能随时发生变化。
  • 它接受该地址的内容并将其视为int,然后返回。
  • static表示该函数具有本地范围。

请注意,如果目标操作系统使用虚拟寻址(例如PC),如果您尝试运行此代码,操作系统只会给您一记耳光。

总而言之,这是编写得很糟糕的代码,既不安全,定义也不便携。你不会通过盯着它获得任何有价值的知识。

答案 3 :(得分:0)

它将val强制转换为指针并返回其值。致myfunc()的电话只有在您看起来才有效     int i,j;

i = 10;
j = myfunc( (int)&i )` 

应该将j设置为10

但是它不适用于sizeof(int *)为8且因此大于sizeof(int)的64位系统或某些sizeof(int) == 2