Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

Re: Volatile modifier

2012-04-19 by Gregory N

> Do you have a suggestion on how we can achieve clarity?

I haven't been following every message in this list, so pardon me if I am repeating something.

It seems to me that the lack of clarity is because people are attempting to define the volatile storage class based on when and how to use it, not what it is.

If you define volatile by what it is, then its usage follows rather naturally.  The storage class volatile simply instructs the compile to avoid optimization of any operations involving the thing that is marked volatile.

The name volatile is itself misleading because it implies one usage of the storage class rather that what it is. nooptimize would be a more meaningful name.

[This, by the way, is a classic job interview C question.  "What does the volatile storage class mean?"  If you give any anser other than the above answer, you would probably fail the interview question.]

Now how does that tie into the rest of this discussion.  Well, the optimizer does things that you may not want it to do.  For example, if you have a load from a symbolic name within a loop but never modify the value within the loop, the optimizer is free to move the load outside of the loop.  This would be catastrophic if the thing you are loading is a register or is a value that could be modified by an interrupt or another thread.

volatile says don't optimize... don't move the load outside the loop.

Basically, anytime the compiler thinks it knows the value of something, it can suppress re-loading it as part of the optimization.

Another case is where the optimizer notices that a variable read but is never used, in that case the optimizer says, "the variable is never used I can eliminate it".  But if you are reading a machine register you probably want to read the value even though you don't use the value that you read.

volatile says don't optimize... read the value even though you don't use it.

Here is a complete unrelated use of volatile.  Suppose I have a timing loop like this:

void wait_a_bit(void)
{
  int i;
  for (i = 0; i < 1000; i++)
  ;
}

What can go wrong with that?  Well, first if you are doing really aggressive optimization, the compiler might decide that function does nothing and eliminate it completely.

But suppose it doesn't do that. That is still a problem... the problem is that the variable i will be a memory location if optimization is OFF but will be a register value if the optimization is ON.  So if I calibrated my timing loop with optimization OFF, it will be broken when optimization is turned on.  The fix?

volatile says don't optimize... don't convert the variable i to a register variable.

void wait_a_bit(void)
{
  volatile int i;
  for (i = 0; i < 1000; i++)
  ;
}

will behave approximately the same whether optimization is enabled or not.

volatile can help in many different ways and is easy to understand when to use it if you remember that all it does is turn optimization off.

Greg

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.