为什么 C 中需要 volatile
?它是干什么用的?它会做什么?
最佳答案
volatile
告诉编译器不要优化与 volatile
变量有关的任何内容。
至少有三个使用它的常见原因,所有原因都涉及变量的值可以在没有可见代码的操作的情况下改变的情况:
- 当您与更改值本身的硬件交互时
- 当有另一个正在运行的线程也使用该变量时
- 当存在可能会更改变量值的信号处理程序时。
假设您有一小块硬件被映射到 RAM 中的某处并且有两个地址:一个命令端口和一个数据端口:
typedef struct
{
int command;
int data;
int isBusy;
} MyHardwareGadget;
现在你想发送一些命令:
void SendCommand (MyHardwareGadget * gadget, int command, int data)
{
// wait while the gadget is busy:
while (gadget->isbusy)
{
// do nothing here.
}
// set data first:
gadget->data = data;
// writing the command starts the action:
gadget->command = command;
}
看起来很简单,但它可能会失败,因为编译器可以自由更改数据和命令的写入顺序。这将导致我们的小工具使用先前的数据值发出命令。另请查看忙循环中的等待。那个将被优化掉。编译器会很聪明,只读取一次 isBusy
的值,然后进入无限循环。这不是你想要的。
解决这个问题的方法是将指针 gadget
声明为 volatile
。这样编译器就被迫按照你写的去做。它不能删除内存分配,不能在寄存器中缓存变量,也不能改变分配的顺序
这是正确的版本:
void SendCommand (volatile MyHardwareGadget * gadget, int command, int data)
{
// wait while the gadget is busy:
while (gadget->isBusy)
{
// do nothing here.
}
// set data first:
gadget->data = data;
// writing the command starts the action:
gadget->command = command;
}
关于c - 为什么 C 中需要 volatile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33348279/