7

I read that in some cases (global variable, or while(variable), etc.) if the variables are not defined as volatile it may cause problems.

Would it cause a problem if I define all variables as volatile?

Tevo D
  • 3,351
  • 21
  • 28
Johan Elmander
  • 497
  • 2
  • 6
  • 11
  • 6
    When doing AVR programming, you can use this rule: _If the variable is changed by an interrupt service routine, declare as volatile._ – makes Jul 17 '13 at 20:02

4 Answers4

13

If something outside of the current scope or any subsequent child scope (think: function calls) can modify the variable you are working in (there's a timer interrupt that will increment your variable, you gave a reference to the var to some other code that might do something in response to an interrupt, etc) then the variable should be declared volatile.

volatile is a hint to the compiler that says, "something else might change this variable." and the compiler's response is, "Oh. OK. I will never trust a copy of this variable I have in a register or on the stack. Every time I need to use this variable I will read it from memory because my copy in a register could be out of date."

Declaring everything volatile will make your code slow down a lot and result in a much larger binary. Instead of doing this the correct answer is to understand what needs to be tagged volatile, why it does, and tagging appropriately.

Chris Raplee
  • 336
  • 1
  • 5
  • 1
    _"you gave a reference to the var to some other code that might do something in response to an interrupt, etc"_ - What other code do you mean? Do you mean functions called by an interrupt? (function calls in ISR:s should be avoided.) Simply put, I think the OP should declare as volatile any variable that is modified by an ISR. Of course assuming this is not a multithreaded environment. – makes Jul 17 '13 at 20:46
  • mizo: When coding on an AVR chip there are usually some libraries in use which are provided through a community (as with Arduino), from the vendor, or through some collaboration, "Jeff, work on the code for running the drive motors, I'll take the rotary encoders, Bob, you take care of the bump sensors." Those are all examples of "other code" which might change the state of a variable. To the rest: Of course an ISR should not call functions (usually) but that it is important to note that if I register with a timer library to have numTicks updated by that lib, then numTicks should be volatile. – Chris Raplee Jul 18 '13 at 15:07
  • volatile is not a hint to the compiler. It is a defined command to the compiler to not optimise accesses to this variable. I'm away from my copy of the C std, so I can't look it up precisely ATM – Martin Thompson Jul 22 '13 at 11:19
4

A volatile variable must have its memory accesses honoured by the compiler.

This means that:

  • If you read the value of the variable, the compiler is not allowed to reuse a value it already "knows" about. For example, it might be in an external device register and subject to change by the peripheral hardware.
  • If you write something to the variable, the compiler must write to that memory. It is not allowed to look around and say "well, nothing else uses that variable, so I don't really need to write it". For example, it might again be an external peripheral register (maybe the Tx FIFO of a UART).

Note that volatile is not (always) sufficient for communication between threads (or between main loops and interrupt service routines: https://stackoverflow.com/a/2485177/106092. See also https://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt


Only make things volatile which need to be. If you find yourself having to make things volatile to make them work it comes down to one of two things:

  • A compiler bug
  • Your code not being correct

In my experience it's almost always the latter, but you might need to consult a c-lawyer on why!


But in answer to your actual question, if you make everything volatile, the code should still work fine, although you may have performance limitations that you don't need to have!

Community
  • 1
  • 1
Martin Thompson
  • 16,395
  • 1
  • 38
  • 56
1

A variable is said to be volatile if its value can change at any moment independently of the program. It is useful if another program (or thread), or an external event (keyboard, network ...) can modify the variable. It tells the compiler to reread the value of the variable from its original location each time the variable is accessed. It prevents the compiler to optimize memory access. So declaring each variable volatile may slow down the program.

By the way: I know nothing about specificity of AVR programming.

hivert
  • 10,579
  • 3
  • 31
  • 56
  • is the only bad thing about defining all variables as volatile that it would slow down the process a little bit? – Johan Elmander Jul 17 '13 at 19:58
  • As far as I know you will only get slow down. However a little bit can be much more that what you thing. – hivert Jul 17 '13 at 20:06
  • hivert: a "little bit" has a much different meaning in environments where the number of instructions retired per second is north of a billion and environments where you've got a dozen million instructions per second. Plus: the extra instructions to ditch what's in register & refresh from memory are real. When you need your bin to fit in just a couple k of memory blowing dozens upon dozens of instructions just to, "pull that variable from memory...again..." becomes a real concern. – Chris Raplee Jul 18 '13 at 15:14
  • That's what I meant by "much more that what you thing" – hivert Jul 18 '13 at 15:18
1

If you need to configure all variable as volatile , then there is some deep rooted design issue with your software. Yes, it will decrease by performance. But how much? We don't know unless you provide the spec of the CPU and its instructions.

user2584960
  • 645
  • 1
  • 6
  • 20