Volatile is not preventing a variable from being optimized - c

As I know, "volatile" keyword is used to prevent compiler to optimize an unused variable. I am working with an STM32 board and I declare and initialise a variable as follows;
volatile uint32_t errorCallbackCounter = 24 ;
And never use it again.
While debugging, this variable is not seen. I am checking it with STMStudio( a real time variable watcher ) and when I want to import variables, the adress of errorCallbackCounter is seen as 0x0.
But when I use it in anywhere, it becomes visible.
So volatile keyword is not doing its job or -more probably- I know something wrong about it.
Thanks in advance.

Variables that are never used can be dropped by the linker
The volatile keyword affects the code that accesses the variable, preventing the access from being rearranged or dropped by the compiler. The line above is a variable definition with an initializer, that doesn't count as an access, it gets arranged before main() starts. But if it isn't referenced by accessible program code, isn't accessed at all, the linker thinks that it's safe to remove it, no one would notice.
You can however mark the variable as "it's needed no matter what" with
__attribute__((used))
placed at the end of the definition. This works with gcc, other compilers might have another directive for it. There is also a linker option that I can't recall right now to include all unused data sections in the executable.

volatile means the system will load this variable from memory each time it is accessed.
The compiler is not allowed to store the data directly into an register.
The volatile keyword prevents the compiler from performing optimization on code involving volatile objects, thus ensuring that each volatile variable assignment and read has a corresponding memory access. Without the volatile keyword, the compiler knows a variable does not need to be reread from memory at each use, because there should not be any writes to its memory location from any other thread or process.

Related

Can const variables be modified from elsewhere not known at compile time

If const is a compile time construct, it would mean that only the compiler will ensure that for example if a variable is declared as const, this variable is read only and it is not attempted to be modified by the rest of the code being compiled?
What about if a const variable is a global variable in our code, and our code links to a dynamic library at run time which attempts to write to it? , or if an ISR attempts to update it, which was not in our compiled code?
I believe the compiler can mark const variables to be loaded into the read only data section which would prevent any changing of the variable, but what if it doesn't?
Thanks
the compiler will ensure that for example if a variable is declared as const, this variable is read only and it is not attempted to be modified by the rest of the code being compiled?
Yes, as far as the compiler is able to tell. If your code attempts to write to a const-qualified variable, you will get a compiler error. If you dodge type correctness by for example casting away the const qualifier, then all bets are off.
What about if a const variable is a global variable in our code, and our code links to a dynamic library at run time which attempts to write to it? , or if an ISR attempts to update it, which was not in our compiled code?
Then it should not have been const qualified, or the compiler will make strange assumptions and generate incorrect code.
However, there exist cases where a const variable may be updated from the outside world - it could be a read-only hardware register or an EEPROM memory cell etc.
To prevent the compiler from doing strange assumptions in such special cases, you can then combine const and volatile. All variables that may be updated from an external source, such as hardware or an ISR, should therefore always be declared as volatile.

Is a C compiler obligated to always reload const value from memory?

I have a const variable in my embedded C program. It's defined and initialized with 0 in program code. It's placed in a special ROM area via linker script. One can change the content of the special area via special programming procedure, but it cannot be changed during main program execution.
The question is whether I have to declare the constant as volatile. If it's not marked as volatile, is the compiler allowed to replace all references to it with 0? Or is it obligated to load it at least once during program execution?
It looks like your variable is really a constant (i.e. doesn't change during program execution) with a value unknown to the compiler. If this is the case, you can declare it like this:
extern const int variable;
(i.e. without volatile and without an initializer) and let the linker script or other tools set up the correct value.
The compiler will then be permitted to load it and potentially leave it in a register forever, but not replace it by 0 or any other value at compile time.
If marked as volatile the compiler is obliged to load it from memory every time it needs it value.
If not marked as volatile, the compiler may load it once from memory, store it in a register, and use this register instead of loading it again.
A not-optimizing compiler may do this - but it also may, stupidly, load it every time. (As not reloading is in fact an optimization in itself.)
Optimizing compilers may notice the const and decide it can be compiled with its real, literal value; up to a point where the original constant does not appear at all in the .data section of your program. (Or maybe it does but it never gets "read".)
Since you change the value in a linker script, the compiler cannot "know" the value got changed after compiling. In that case, use volatile: the only way to tell the compiler not to trust that the value is known when compiling.

Alternative to volatile?

I'm using a lot of volatile variables in my embedded firmware, but most of the time there is only one point in a function where I need to be sure the value is recent (at the start). But the rest of the function is referring to the same variable-name, and the value can be changed in the mean time, producing very unexpected code flow / results. I know this can be solved by using a temporary variable inside the function, but I was looking for a better solution.
Now I was wondering, instead of marking the whole variable as volatile, is there a way I could instruct the compiler (gcc) with a special keyword that I want to read the variable as if it was marked volatile, so I can use that keyword only once at the beginning of the function?
I'm a little confused about the scenario - if it's that you want one particular access to a variable to be treated as volatile, use
dest = *(volatile TYPE *)&src;
where TYPE is the type of src. You may also need
asm volatile ("" ::: "memory");
in carefully controlled locations, to prevent the compiler from moving loads/stores of other memory locations across the volatile read.
Also investigate C11's _Atomic types. (I'm not sure if GCC supports these yet.)
If your variable is in memory and your embedded system supports it you could use memory barriers. To make sure that nothing accesses the memory while you are reading the value out.

Volatile variable

Where is a volatile variable stored in the program memory (in which section)?
volatile is a type qualifier not a storage class specifier, so it does not determine storage location at all; it affects the definition of a variable's type, not its storage.
It simply forces the compiler to explicitly read a variable whose type is volatile from the variable's storage location (wherever that may be) rather than assuming that some previously read value in a register for example remains valid.
In C volatile just tells the compiler - "You don't have enough knowledge to assume the value of this variable hasn't changed". There is no "section" eg BSS, CSS for it.
Consider it a flag to the compiler to prevent certain types of optimisations. Its very handy in embedded programming, where memory at a certain address may "change" due to a hardware device input.
Here's a good explanation: http://www.embedded.com/columns/programmingpointers/174300478?_requestid=137658
The volatility of a variable does not change the place in which a variable is stored. What it changes is the semantics around how it is accessed with respect to reads and writes.
I do not believe the C standard says anything about the implementation of volatile. But typically, volatile guarantees release semantics for write operations on a variable and aquire semantics on read operations of a variable. This will not be true for every implementation though and you should read up on what your specific compiler guarantees
volatile has nothing to deal with storage class.
volatile just tells the compiler or force the compiler to "not to do the optimization" for that variable.
so compiler would not optimize the code for that variable and reading the value from the specified location, not through interal register which holds the previous value.
So, by declaring variable as volatile.. it gives garrantee that you will get the latest value, which may be alterred by an external event.
your code may be work fine if haven't declare that variable as volatile, but there may be chance of not getting correct value sometimes..
so to avoid that we should declare variable as volatile.
volatile is generally used when dealing with external events, like interrupts of hardware related pins.
example.
reading adc values.
const voltile means
you can not modify or alter the value of that variable in code. only external event can change the value.
controller pins are generally defines as volatile.
may be by declaring variable as volatile controller will do "read by pin" not "read by latch"... this is my assumtion. may be wrong...
but still there is lots of confusion when to choose variable as volatile..
A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change:
Memory-mapped peripheral registers
Global variables modified by an interrupt service routine
Global variables within a multi-threaded application
Link : http://eetimes.com/discussion/beginner-s-corner/4023801/Introduction-to-the-Volatile-Keyword
So It is proffered to variable as volatile in such cases.
There's no reason for a volatile variable to be stored in any "special" section of memory. It is normally stored together with any other variables, including non-volatile ones. If some compiler decides to store volatile variables in some special section of memory - there's nothing to prevent it from doing so. But at the language level there's absolutely no reason for this.
Why are you asking such a question? What made you think that it should be stored in some special section of memory?
"Volatile" was used in C/C++ specifications to allow use of memory mapped devices. It directs the compiler not to optimize the variable defined with this keyword, just because the variable doesn't seem to change its state in compiler-visible code.

What is the difference between a static global and a static volatile variable?

I have used a static global variable and a static volatile variable in file scope,
both are updated by an ISR and a main loop and main loop checks the value of the variable. here during optimization neither the global variable nor the volatile variable are optimized. So instead of using a volatile variable a global variable solves the problem.
So is it good to use global variable instead of volatile?
Any specific reason to use static volatile??
Any example program would be appreciable.
Thanks in advance..
First let me mention that a static global variable, is the same as a global variable, except that you are limiting the variable to the scope of the file. I.e. you can't use this global variable in other files via the extern keyword.
So you can reduce your question to global variables vs volatile variables.
Now onto volatile:
Like const, volatile is a type modifier.
The volatile keyword was created to prevent compiler optimizations that may make code incorrect, specifically when there are asynchronous events.
Objects declared as volatile may not be used in certain optimizations.
The system always reads the current true value of a volatile object at the point it is used, even if a previous instruction asked for a value from the same object. Also, the value of the object is written immediately on assignment. That means there is no caching of a volatile variable into a CPU register.
Dr. Jobb's has a great article on volatile.
Here is an example from the Dr. Jobb's article:
class Gadget
{
public:
void Wait()
{
while (!flag_)
{
Sleep(1000); // sleeps for 1000 milliseconds
}
}
void Wakeup()
{
flag_ = true;
}
...
private:
bool flag_;
};
If the compiler sees that Sleep() is an external call, it will assume that Sleep() cannot possibly change the variable flag_'s value. So the compiler may store the value of flag_ in a register. And in that case, it will never change. But if another thread calls wakeup, the first thread is still reading from the CPU's register. Wait() will never wake-up.
So why not just never cache variables into registers and avoid the problem completely?
It turns out that this optimization can really save you a lot of time overall. So C/C++ allows you to explicitly disable it via the volatile keyword.
The fact above that flag_ was a member variable, and not a global variable (nor static global) does not matter. The explanation after the example gives the correct reasoning even if you're dealing with global variables (and static global variables).
A common misconception is that declaring a variable volatile is sufficient to ensure thread safety. Operations on the variable are still not atomic, even though they are not "cached" in registers
volatile with pointers:
Volatile with pointers, works like const with pointers.
A variable of type volatile int * means that the variable that the pointer points to is volatile.
A variable of type int * volatile means that the pointer itself is volatile.
They are different things. I'm not an expert in volatile semantics. But i think it makes sense what is described here.
Global
Global just means the identifier in question is declared at file-scope. There are different scopes, called function (where goto-labels are defined in), file (where globals reside), block (where normal local variables reside), and function prototype (where function parameters reside). This concept just exist to structure the visibility of identifiers. It doesn't have anything to do with optimizations.
Static
static is a storage duration (we won't look at that here) and a way to give a name declared within file scope internal linkage. This can be done for functions or objects only required within one translation unit. A typical example might be a help function printing out the accepted parameters, and which is only called from the main function defined in the same .c file.
6.2.2/2 in a C99 draft:
If the declaration of a file scope
identifier for an object or a function
contains the storage class specifier
static, the identifier has internal
linkage.
Internal linkage means that the identifier is not visible outside the current translation unit (like the help function of above).
Volatile
Volatile is a different thing: (6.7.3/6)
An object that has volatile-qualified
type may be modified in ways unknown to
the implementation or have other
unknown side effects. Therefore any
expression referring to such an object
shall be evaluated strictly according
to the rules of the abstract machine,
as described in 5.1.2.3. Furthermore,
at every sequence point the value last
stored in the object shall agree with
that prescribed by the abstract
machine, except as modified by the
unknown factors mentioned
previously.
The Standard provides an excellent example for an example where volatile would be redundant (5.1.2.3/8):
An implementation might define a
one-to-one correspondence between
abstract and actual semantics: at
every sequence point, the values of
the actual objects would agree with
those specified by the abstract
semantics. The keyword volatile
would then be redundant.
Sequence points are points where the effect of side effects concerning the abstract machine are completed (i.e external conditions like memory cell values are not included). Between the right and the left of && and ||, after ; and returning from a function call are sequence points for example.
The abstract semantics is what the compiler can deduce from seeing only the sequence of code within a particular program. Effects of optimizations are irrelevant here. actual semantics include the effect of side effects done by writing to objects (for example, changing of memory cells). Qualifying an object as volatile means one always gets the value of an object straight from memory ("as modified by the unknown factors"). The Standard doesn't mention threads anywhere, and if you must rely on the order of changes, or on atomicity of operations, you should use platform dependent ways to ensure that.
For an easy to understand overview, intel has a great article about it here.
What should i do now?
Keep declaring your file-scope (global) data as volatile. Global data in itself does not mean the variables' value will equal to the value stored in memory. And static does only make your objects local to the current translation unit (the current .c files and all other files #include'ed by it).
The "volatile" keyword suggests the compiler not to do certain optimizations on code involving that variable; if you just use a global variable, nothing prevents the compiler to wrongly optimize your code.
Example:
#define MYPORT 0xDEADB33F
volatile char *portptr = (char*)MYPORT;
*portptr = 'A';
*portptr = 'B';
Without "volatile", the first write may be optimized out.
The volatile keyword tells the compiler to make sure that variable will never be cached. All accesses to it must be made in a consistent way as to have a consistent value between all threads. If the value of the variable is to be changed by another thread while you have a loop checking for change, you want the variable to be volatile as there is no guarantee that a regular variable value won't be cached at some point and the loop will just assume it stays the same.
Volatile variable on Wikipedia
They may not be in different in your current environment, but subtle changes could affect the behavior.
Different hardware (more processors, different memory architecture)
A new version of the compiler with better optimization.
Random variation in timing between threads. A problem may only occur one time in 10 million.
Different compiler optimization settings.
It is much safer in the long run to use proper multithreading constructs from the beginning, even if things seem to work for now without them.
Of course, if your program is not multi-threaded then it doesn't matter.
I +1 friol's answer. I would like to add some precisions as there seem to be a lot of confusions in different answers: C's volatile is not Java's volatile.
So first, compilers can do a lot of optimizations on based on the data flow of your program, volatile in C prevents that, it makes sure you really load/store to the location every time (instead of using registers of wiping it out e.g.). It is useful when you have a memory mapped IO port, as friol's pointed out.
Volatile in C has NOTHING to do with hardware caches or multithreading. It does not insert memory fences, and you have absolutely no garanty on the order of operations if two threads do accesses to it. Java's volatile keyword does exactly that though: inserting memory fences where needed.
volatile variable means that the value assinged to it is not constant, i.e if a function containing a volatile variable "a=10" and the function is adding 1 in each call of that function then it will always return updated value.
{
volatile int a=10;
a++;
}
when the above function is called again and again then the variable a will not be re-initialised to 10, it will always show the updated value till the program runs.
1st output= 10
then 11
then 12
and so on.

Resources