C语言中的volatile关键字?

时间:2011-04-28 17:07:35

标签: c volatile

我对C语言中的volatile有疑问。

我读了一些教程,但仍然无法弄清楚,有些人说,volatile告诉编译器优化器,不应该以某种方式优化涉及这个变量的操作。 这意味着只要变量的值在寄存器中发生变化,该值就会影响内存。

还有一些人说volatile是指可以通过此代码之外的方式更改值。

我无法理解第二种说法,因此可以通过此代码之外的方式更改volatile变量?怎么样?这两个说得对吗?

6 个答案:

答案 0 :(得分:41)

声明“可以通过此代码之外的方式更改值”基本上意味着另一个程序或硬件可以更新该变量。这完全有可能。考虑这一点的一种方式是将此概念与多个程序之间共享的文件相关联。许多程序可以同时打开,写入和读取文件。当您从文件中读取时,要确保您正在阅读最新更新,而不是最旧的更新。

回到volatile关键字,在变量之前放置volatile实际上做了同样的事情。它确保您从变量中读取的内容不是基于编译器的优化或程序具有的变量的旧副本。此外,volatile关键字确保在每次访问时从内存中获取变量。因此,关于volatile关键字,这两个语句都是正确的。

答案 1 :(得分:19)

C不一定适用于计算机。例如,如果您正在为Game Boy Advance开发,您经常会遇到由硬件修改的内存位置,因此您可能无法修改代码中的变量,但无论如何它都会被修改。这就是volatile的含义。

通过添加volatile关键字,您告诉编译器“存储在此变量(内存位置)中的值可能会在我的代码执行任何操作时发生更改。”

答案 2 :(得分:15)

考虑以下任何一种情况:

  • 多线程应用程序,
  • 使用共享内存的应用程序,
  • 在将I / O寄存器映射到地址空间的平台上运行的应用程序
  • 在后台发生硬件DMA的应用程序。

在每种情况下,都可以在当前线程之外更改内存。

注意“随时变量的值在寄存器中发生变化,那么值应该影响内存”是正确的,只是不太清楚。

答案 3 :(得分:5)

可以通过多种方式在程序代码之外更改内存位置。例如,从磁盘读取的DMA可以写入缓冲区,或者由于设备上的某些事件,内存映射设备可能会更改位置。

答案 4 :(得分:3)

这个地址,例如,多线程应用程序:变量的值可以由多个线程更改,因此必须与每次访问的内存“同步”(无论是读取还是写入值)

答案 5 :(得分:1)

声明一个volatile变量意味着,您指示编译器不要优化该变量周围的代码片段。这是为了强制cpu不要使用本地寄存器或高速缓冲存储器中的变量值,而是每次从主存储器中获取值。