[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] "Volatile"

From: Dean Hall
Subject: Re: [avr-gcc-list] "Volatile"
Date: Sun, 17 Apr 2005 10:46:44 -0500

I have had to work with software engineers who have worked in embedded
systems for several years and cannot tell you the effect of the static
modifier, let alone volatile.  A popular misconception was that these
keyword affect whether or not a variable is cached (pause for laughter).

To an otherwise fine post, I would like to raise two issues:

With respect, Graham, I think you may have misunderstood the "cached" terminology here. Obviously an AVR doesn't have large instruction or data cache like a PowerPC or Pentium. But the compiler does cache a variable's value into a register and re-use that register (without loading the variable from memory again) as an optimization.

Using volatile is a directive to the compiler to always load/store that variable from/to memory every time it is referenced in the source code.

Using volatile can then become confusing for a trivial fragment such as this:
        volatile v = 42;
        v = ((v=12) | (~v) | (!v));
Does this cause two loads of v? Is v equal to twelve or forty two when ~v is executed? Answers are left as an exercise to the reader. But let me give this advice to all: when declaring a volatile variable, use it only in very simple statements. In the embedded space, especially when dealing with volatile, it is a good programming practice to break complex actions into multiple lines of simple statements. This makes things clear to the reader and assists debugging.

Even on this list, some of the experts are not 100% clued in. A while ago I
asked if I was wrong to expect that an assignment to a volatile object
should result in exactly one machine-level write to the memory location in which it is stored. Several responders told me that I should not expect
this and that the compiler is at liberty to implement the assignment as
multiple writes even when the variable is declared volatile.  Further
research indicated that this was wrong and my expectation is correct.

In general, a compiler is free use any number of instructions when translating a line of C to assembly. The compiler's goal is to use as few instructions as possible to make execution faster. Lets take the example "volatile v = 42;" After loading 42 into a register, this may result in a store-direct (STS) instruction or a store-indirect (ST) instruction. The store-indirect uses X, Y or Z as an address register. So, would you count the instructions that put v's address into the address register?

Also be aware that the compiler is within its right to convert the line "v = 42;" into two, three, or N identical store instructions, even though it is redundant. No compiler I know would do this, but one must not rely on optimal C-to-ASM translation, only on logical behavior. If one needs exact assembly instructions, one should write in assembly.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]