开发者

Question about the volatile keyword

I know that by the volatile keyword,

volatile int 开发者_如何学Gok=7; 

we hint the compiler that the variable can be changed at any time but what about a simple int k=7? Can we change it at any time because it is not constant? What is different?


volatile prevents compiler optimizations and tells the compiler that the contents of the variable declared volatile can change at any time (i.e. a hardware device, interrupt, or another thread kicks in and writes into the variable's memory location). This means, caching values in CPU registers is not possible.

volatile int a = foo();
d=a+4;
e=a+4;
f=a+4;

Here, the compiler is forced to read a from memory every time it is used. If there was no volatile, precomputing a+4 would be a valid (and effective) optimization.

volatile int a = 4;
return a+5;

Here, the compiler is not allowed to optimize this to a simple return 9; because the contents of a might change between initialization (line 1) and first use (line 2);


It's used in low level programming with interrupts and so on mostly

volatile int count;

void test()
{
   while(count< 100) 
   {
        // do nothing
   }
}

//
// Interrupt function called by the hardware automatically at intervals
//
void interrupt()
{
    count = count + 1;
}

if you don't declare the variable as volatile the compiler will probably notice that count can't change in the while loop and so won't bother to actually read the value every time from memory so it will never exit the loop.

If you declare it volatile then the compiler will read the value from memory every time as you've told it that the value might change without notice...

Another use is to map hardware ports.

On a microcontroller you might have some digital inputs which "appear" at a certain memory address. You can read them as if they were a variable but of course the value will potentially change all the time depending on the input signals. Declaring the value as volatile will indicate to the compiler that yes you actually do need to read this memory location every single time because it might have changed, and no you can't assume that it won't change unless you change it.

Unless you are using low level interrupts or some uses of threading then you don't need to use it.

EDIT: To be clear, volatile is NOT for synchronization between theads in standard c++, it only does a part of what is necessary. The last sentence in my original post could be misleading. The examples and stuff about hardware interrupts etc in my post are what volatile is for, it absolutely ISN'T for threading and don't even try to use it for that.

I originally wrote "some uses of threading" because on some platforms it might be sufficient to use volatile. This is BAD ADVICE in general but if you have a single core and all writes are visible to all "threads" then it might work for you. For example on a microcontroller with a simple interrupt based thread switching system it would likely "work" even though not guarenteed by the standard. But don't do it. In general it's just wrong, and c++11 has ways that actually work (remember this answer was written pre c++11)


Each time the compiler comes across an access to k, it will refetch it from memory instead of optimizing the code to collapse multiple uses of it.

int k = 7;
int i = k;
int j = k;

becomes equivalent to:

int k = 7;
int i;
int j;
i = j = k;

but

volatile int k = 7;
int i = k;
int j = k;

does not.


Volatile forces the variable to be read from memory each time instead of caching it.


Can we change it at any time because it is not constant?

Yes, you can change it, but C++ doesn't tell what should happen bellow. That depends on the abstract machine (i.e. the platform you are working on).

If the volatile variable doesn't map to a register of a HW device, then your volatile variable will behave almost like a normal variable. I said almost, because you will not be able to pass it to methods and functions expecting non-volatile int, like this one :

void foo( int & p );

If the variable maps to a register of a HW device, then trying to write to a read-only registers depends on the device. It may simply ignore writes, but it can also somehow indicate an error - c++ doesn't tell anything.


volatile is a cv-qualifier, used to access hardware registers, or part of memory which can be modified externally (for example, by a controller).

The c++ standard in [dcl.type.cv]/7 tells :

[ Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C ++ as they are in C. — end note ]

The Stay away from Volatile in threaded code? article tells what the volatile is good for :

The volatile keyword is not a threading or synchronization primitive in portable C or C++. It was mainly intended to

1) Allow access to memory mapped devices (I.e. pointers to data structure in coherent memory that can be modified by I/O devices.)
2) Variables in signal handlers and between setjmp and longjmp (ref: Volatile at Wikipedia)

Another article Volatile: Almost Useless for Multi-Threaded Programming tells :

Hans Boehm points out that there are only three portable uses for volatile. I'll summarize them here:
* marking a local variable in the scope of a setjmp so that the variable does not rollback after a longjmp.
* memory that is modified by an external agent or appears to be because of a screwy memory mapping
* signal handler mischief

and

If you are multi-threading for the sake of speed, slowing down code is definitely not what you want. For multi-threaded programming, there two key issues that volatile is often mistakenly thought to address:
* atomicity
* memory consistency, i.e. the order of a thread's operations as seen by another thread.

What is important is that volatile should not be used in multi-threaded environment as synchronization mechanism, or as to provide atomic access, since it may work on some compilers, and not on other. For that there are other tools for synchronization (for example semaphores, or mutex with conditional variable) and atomic access (atomic library.


Volatile keyword is used to inform the compiler not to predict/assume/believe/presume the value of the particular variable which has been declared as volatile.

This variable can change by internal and external sources, so you can definitely change it.

const volatile int k=5; <==== This could not be change by your program but can change by external sources, const makes its read only, only for compiler or programmer

Source : - Volatile variable in C

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜