7

我读到在某些情况下(全局变量或 while(变量)等)如果未定义变量,因为volatile它可能会导致问题。

如果我将所有变量都定义为 volatile 会导致问题吗?

4

4 回答 4

12

如果当前范围之外的某些内容或任何后续子范围(想想:函数调用)可以修改您正在使用的变量(有一个计时器中断会增加您的变量,那么您将 var 的引用提供给其他可能的代码做一些事情来响应中断等)然后变量应该被声明为 volatile。

volatile 是对编译器的提示,它说“其他东西可能会改变这个变量”。编译器的响应是,“哦。好吧。我永远不会相信我在寄存器或堆栈中的这个变量的副本。每次我需要使用这个变量时,我都会从内存中读取它,因为我的副本在寄存器中可能已经过时了。”

将所有内容声明为 volatile 会使您的代码变慢很多,并导致二进制文件更大。而不是这样做,正确的答案是了解什么需要标记为 volatile,为什么要标记,并适当地标记。

于 2013-07-17T19:56:09.017 回答
4

一个 volatile 变量的内存访问必须被编译器认可。

这意味着:

  • 如果您读取变量的值,则不允许编译器重用它已经“知道”的值。例如,它可能位于外部设备寄存器中,并且会受到外围硬件的更改。
  • 如果您向变量写入内容,编译器必须写入该内存。不允许环顾四周说“好吧,没有其他东西使用那个变量,所以我真的不需要写它”。例如,它可能又是一个外部外围寄存器(可能是 UART 的 Tx FIFO)。

请注意,这volatile对于线程之间(或主循环和中断服务例程之间的通信)并不(总是)足够:https ://stackoverflow.com/a/2485177/106092 。另见https://www.kernel.org/doc/文档/volatile-considered-harmful.txt


只使需要的东西变得易变。如果您发现自己必须使事情变得不稳定才能使其正常工作,则可以归结为以下两件事之一:

  • 编译器错误
  • 您的代码不正确

根据我的经验,几乎总是后者,但您可能需要咨询 c-lawyer 了解原因!


但是在回答您的实际问题时,如果您使所有内容都变得易变,那么代码应该仍然可以正常工作,尽管您可能有您不需要的性能限制!

于 2013-07-19T09:08:49.257 回答
1

如果一个变量的值可以在任何时候独立于程序发生变化,则称该变量是易失的。如果另一个程序(或线程)或外部事件(键盘、网络 ...)可以修改变量,这将很有用。它告诉编译器每次访问变量时从其原始位置重新读取变量的值。它阻止编译器优化内存访问。因此,将每个变量声明为 volatile 可能会减慢程序的速度。

顺便说一句:我对 AVR 编程的特殊性一无所知。

于 2013-07-17T19:53:30.457 回答
1

如果您需要将所有变量配置为 volatile ,那么您的软件存在一些根深蒂固的设计问题。是的,它会因性能而降低。但是多少钱?除非您提供 CPU 的规格及其说明,否则我们不知道。

于 2013-07-17T20:09:55.323 回答