C语言中的'static volatile'和'static'和'volatile'有何不同?

11

在微控制器编程中,使用变量说明符static volatile的组合与单独使用staticvolatile有什么区别呢?


2
您可能需要参考C11标准(草案n1570)§ 6.2.2标识符的链接性,然后是§ 6.2.4对象的存储期§ 6.7.1存储类说明符 - David C. Rankin
1
这些是关键字、数据类型和限定符。如果你能单独理解它们,会帮助你理解它们的含义以及如何使用它们。也许对你来说是个练习 :) - Milind Deore
@JohnBollinger感谢您对我的问题的重视,尽管它并不是很清晰。无论如何,现在已经过去两年多了,我开始理解这些限定符。只有当我进入到一个需要我使用它们作为替代或必需方式的程序中,我才能真正地理解它们!我学到的主要思想是,通过更高级的代码,我可以学到新的东西。 - R1S8K
@DavidC.Rankin 感谢您提供的参考。 - R1S8K
4个回答

18

static - 在这种情况下,使变量仅在当前文件中可见。 static 对象具有静态存储期。

volatile - 这是给编译器的一个信息,表明对象可以被正常执行路径之外的某些东西改变(例如,中断例程),并保证在任何使用之前读取变量,并在每次更改后写入。 volatile(这是一个非常常见的误解)不保证其他任何事情 - 没有原子性,没有缓存一致性等等。


7

这里提供了很多好的答案,但没有涉及到作用域。

静态变量一旦在作用域内被初始化并稍后更改,它们将保留更改,永远不会被销毁或重新初始化,尤其是当离开作用域时。除非在代码中规定。你可以说,静态变量在其生命周期方面类似于全局变量,但只能在其自己的作用域内访问。

易挥发的部分有强制执行从RAM而不是寄存器或闪存中缓存的变量的倾向。例如,假设某个代码是在特定的优化设置下提交给编译器的。编译器不会假定除了在变量未使用或超出其作用域时清除它们之外还附加了任何其他条件。易挥发性本质上具有双重用途,要么忽略编译器为该变量提供的优化,要么不使用预获取的该变量的副本,除了RAM中的那一个。

静态易挥发的是两种行为的组合,在任何优化之外将该变量持久保存在RAM中。

应用潜在领域:

  • 闪存编程
  • 循环缓冲区
  • 环形缓冲区
  • 并发和多处理/多线程

6

静态的:

静态变量是指一个类变量,它在所有实例之间共享。

易失性的:

易失变量是那些被读取和写入主存储器的变量。它们不会被存储在本地缓存中,总是从主存储器中获取。

例如,有两个线程使用私有易失变量private volatile int x;。如果线程A调用write(x)并且线程B调用read(x),则两次都将从主存储器中读取和写入,而不使用线程的本地缓存。

静态易失性的:

即使静态变量是共享变量,但在不同的线程中,一个静态变量可以存在于线程的本地缓存中并具有不同的值。为了使其对所有线程一致,只需将其声明为static volatile。这样每次它都将从主存储器中获取。


6
这个问题标记为“C”。在C语言中,“static”与类没有任何关系。 - Dominick Pastore
1
类与静态有什么关系?这有点误导。 - Abhinandan

2
对于关键字staticvolatile已经有足够的文献解释了,例如: TWI接口的相关问题上,需要使用volatile,因为修改这些变量的函数可能会从不同的中断服务处理程序中调用。如果去除volatile,编译器将会优化代码,但不知道代码可能会被中断,这可能导致故障。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接