What is the difference between volatile & extern? - c

Few days back i had an interview but, still I am searching for the answer.
I would like to understand the significance of using volatile keyword.
Find the code below: Two different scenario.
//project1
//File1.c
int abc;//Global variable
/*And this variable is getting used in some other files too.*/
if(abc == 3) //Say
{
printf("abc == 3");
}
else
{
printf("abc != 3");
}
/*So if or else part will not be optimized
because "abc" can not be predicted,
the value can chage at any point of time */
//Project2
//file1.c
volatile int abc;//Global variable with volatile keyword
/*And this variable is getting used in some other files too.*/
if(abc == 3) //Say
{
printf("abc == 3");
}
else
{
printf("abc != 3");
}
/*So if or else part will not be optimized
because "abc" can not be predicted as it is declared as volatile,
the value can chage at any point of time */
Why we should use volatile keyword instead?

As Tony Delroy explained in its comment, extern and volatile are quite different.
Volatile keyword protects your variable from being aggressively optimised. An optimised variable can be invisible to other threads and never reach main memory. Sometimes, compiler can even squeeze entirely a variable if it's not needed. Compiler base its guess with your source code as its only input. Sometimes, there is some external events which can change your variable value. It could be an hardware device or an other process, for instance.
=> Concretely, compiler disables some optimisations to this variable, so it can behave as you want it to.
Extern is not about cache vs memory. Extern is just about accessing a variable which lives in an other object files. See this short example of what kind of assembly code is generated for an extern access.
Those extern variables are optimised in their own object file as far as it's possible. There's no question about to protect it or not.
=> Concretely, compiler indicates an external reference needing to be solved at link time

volatile in declaration or prototype say always load/store value from/to memory regardless local, static or extern this vlaue (but in case of local it is not always meaningful).
Also using volatile keyword in regular source are untypically. It is useful only for hardware which map hardware registers to memory (like in ARM architecture), in special cases of kernel/driver development.
If you use volatile in GUI or ecommerce code you probably wrong...

volatile usually means one or more of the following:
The variable may get changed by another OS thread
The normal flow of execution in the program may be interrupted by a signal and the signal handler might change the variable
The normal flow of execution is running a loop, the variable is being read within the loop, and the variable is changed by means of point 1 or 2
volatile means that throughout the lifetime of the program there are two (or more) reads R1 and R2 of the variable, and some other event happening inbetween R1 and R2 will change the variable outside of the normal flow of execution.
extern means that the variable has been defined somewhere elsewhere and that the program is reusing that definition.

I don't quite agree with the previous answers so here are my two cents.
By declaring a variable volatile you're telling the compiler that its value can change at any time and that it cannot make any assumptions about the variable's value, not even in two consecutive (assembler) instructions. In consequence any use of the variable must be done by accessing the actual variable and not a cached value.
In the code you provided there is no behavioural difference between abc being global, extern or volatile because if()/else only evaluates the variable once. There is a difference however if you change the else by a second if, as in:
if(abc == 3)
{
printf("abc == 3");
}
if (abc != 3)
{
printf("abc != 3");
}
If abc is NOT declared volatile, the compiler may optimize the second if and replace it by an else statement, in consequence abc would only be read and evaluated once, meaning either the first xor the second prints will be executed (but not both and also not none).
If abc IS declared volatile (no matter if local, global or extern), the compiler is forced to evaluate abc twice because its value could have changed in between. This means that any of the two prints, or both, or none, may be executed.
Extern is a different story entirely. All it does is tell the compiler that the variable has been defined in another file (whose address will be provided at link time). If the compiler can predict that the value of abc won't change between the two if statements (it doesn't matter how the compiler might be able to), then it may still optimize the second if into an else and reduce the two abc evaluations to one.

Essentially, volatile is used to indicate that a variable's value will be modified by different threads.
Declaring a volatile Java variable means:
The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory";
Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.
Extern essentially means that all modules can use the defined variable.

Related

Volatile is not preventing a variable from being optimized

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.

C: Using static volatile with "getter" function and interruptions

Suppose I have the following C code:
/* clock.c */
#include "clock.h"
static volatile uint32_t clock_ticks;
uint32_t get_clock_ticks(void)
{
return clock_ticks;
}
void clock_tick(void)
{
clock_ticks++;
}
Now I am calling clock_tick (i.e.: incrementing clock_ticks variable) within an interruption, while calling get_clock_ticks() from the main() function (i.e.: outside the interruption).
My understanding is that clock_ticks should be declared as volatile as otherwise the compiler could optimize its access and make main() think the value has not changed (while it actually changed from the interruption).
I wonder if using the get_clock_ticks(void) function there, instead of accessing the variable directly form main() (i.e.: not declaring it as static) can actually force the compiler to load the variable from memory even if it was not declared as volatile.
I wonder this as someone told me this could be happening. Is it true? Under which conditions? Should I always use volatile anyway no matters if I use a "getter" function?
A getter function doesn't help in any way here over using volatile.
Assume the compiler sees you've just fetched the value two lines above and not changed it since then.
If it's a good optimizing compiler, I would expect it to see the function call has no side effect simply optimize out the function call.
If get_clock_ticks() would be external (i.e. in a separate module), matters are different (maybe that's what you remember).
Something that can change its value outside normal program flow (e.g. in an ISR), should always be declared volatile.
Don't forget that even if you currently compile the code declaring get_clock_ticks and the code using it as separate modules, perhaps one day you will use link-time or cross-module optimisation. Keep the "volatile" even though you are using a getter function - it will do no harm to the code generation in this case, and makes the code correct.
One thing you have not mentioned is the bit size of the processor. If it is not capable of reading a 32-bit value in a single operation, then your get_clock_ticks() will sometimes fail as the reads are not atomic.

Use the value of global variable in any other function as its value changes inside another function

say i am using a global variable to hold the value of a signal (in a schematics for a circuit board sense) in one function
void randomfunction()
{
for(t=lnnew,s=node->name;*s;)
{
if()
//some code
else
*t=*s;
t++;
s++;
}
printf("%s \n",lnnew); //so now here lnnew is holding new values of signal and when i print this, every time new value of signal is printed and i have declared it as global
}
now how can i use this global variable inside any other function say writelnnewvalue() so that when ever value of lnnew changes in randomfunction(), it also get changes and printed in writelnnewvalue () function?
I had asked similar type of question in this link , if it seems to be exact copy then mark it as duplicate.
You need to declare your variable in a header (.h file) that is included in all compilation units that use it:
extern volatile int lnnew;
Have one compilation unit (.c file) actually define it
volatile int lnnew;
Then it will be usable everywhere where you include the header. volatile here indicates to the compiler that that variable is subject to unpredictable changes and is not to be cached.
You can use two different threads to perform these tasks. Use a flag which is updated on the change of lnnew in one thread (which will run randomfunction()) & use other thread (which will run writelnnewvalue()) conditioned on this flag, to print whatever is desired.
You can find more about multithreaded programming on Internet. A few links I found:
Link 1
Link 2
Link 1 has code examples with explanation.

Im getting the error: register name not specified for ‘i’

#include <stdio.h>
register int i = 10;
int main(void)
{
printf( " i = %d \n ", i );
return 0;
}
Here i declared the variable i as register. But, while compiling its showing the following error
" error: register name not specified for ‘i’ "
Why we should not use register keyword in global ?
A register variable is a type of local variable.
It is a hint to store the value in a register for faster access.
A register variable can not be global or static.
It can be defined only in a block.
Also please format the code you post
A register variable cannot be used as a "global" variable, because file scope variables have static storage, thus by definition they have an address. register variables are exactly the contrary, that are variables for which you, the programmer, promise to never take their address. So combining the two makes not much sense.
BTW, the error message that you get is not very helpful. It seems that your compiler is referring to an extension that allows to fix a register variable to a particular hardware register. If you post such an error message please also give an indication which compiler and/or platform you are using.
The reason we should not use register keyword in global is that the life of variable defined to be of register storage class is within the block in which the variable is defined.
A value stored in CPU register can always be accessed faster than the one that is stored in memory. Therefore, if a variable is used at many places in a program, it is better to declare its storage class as register.
A good example of frequently used variables is loop counters.we can name their storage class as register.
#include<stdio.h>
int main()
{
register int i;
for(i=1;i<=10;i++)
printf("%d\n",i);
return 0;
}
Use of register is obsolete on most modern compilers. Don't use it.
It used to be the case that compilers were not smart enough to determine which variables would be accessed most often and therefore should be assigned a permanent place in a register. But modern compilers use techniques such as static single assignment and register allocation by colouring such that the compiler is far better than you at knowing when a variable should be in a register and when it should be "spilled" out to memory.
Furthermore, register places restrictions on its variable. You can't have a pointer to a register variable, because pointers point to memory locations, and the variable isn't in memory (at least conceptually). And a register variable must be an automatic variable -- commonly known as a "stack" variable. Therefore it must be a local variable within a function, and not qualified as static or extern.
In short, using register never provides performance gains in modern compilers, but it does provide programmer headaches. Premature optimization's biggest weapon -- wasting programmer time with false promises of execution time savings -- strikes again.

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