问题
The volatile
keyword tells the compiler not to optimize the variable which is prefixed. The variable may change during run time by unknown source (not known by the compiler) maybe by an external interrupt etc.
Is there any other advantage of volatile
?
Does volatile
apply to reading from files?
回答1:
volatile
keyword says to compiler do not optimize the variable which is prefixed with, the variable may change during run time by unknown source(not known to compiler) may be by an external interrupt etc.
No. The volatile
keyword does not tell the compiler to disable or not optimize a variable; the volatile
keyword tells the compiler that the variable (or rather the memory that the variable represents) may be modified externally to the program.
This has the effect that the compiler is no longer able to do the necessary analysis to determine if various optimizations are safe (that is functionally equivalent), so the compiler does not perform those optimizations. This is a necessary side-effect, but not the primarily purpose for the existence of the keyword.
The usage of volatile
as a somewhat or slightly portable hack of acting like a pragma
to disable the compiler's optimization is a fairly common pattern. Outside of embedded programming, this may be its most commonly encountered usage for application programmers.
The compiler knows all the interrupts of that controller. So in that case how the
volatile
keyword helps?
The volatile
keyword means the memory contents can be modified outside of the program's control, either in another process, thread, or by external signals such as a hardware interrupt.
Compilers don't "know" about interrupts, there may be system header files distributed with a compiler that define symbolic names for an interrupt, but that does not mean the compiler understands them.
Is there any other advantage of
volatile
?
Not that I can think of, beside what's described here.
[Does]
volatile
appl[y] to reading from files?
Except when used as an form of inter-process communication (IPC) or as a semaphore, the contents of a file are normally controlled by a single process, so the usage of volatile
is not necessary.
回答2:
volatile
actually tells the compiler the value of the variable may be changed outside its control flow. The most popular would be an interrupt or interrupt handler or a hardware register. For the latter, the compiler does actually not know when its value changes. Nor does it for an interrupt, as that only occurs at run-time.
Note that C assumes a single threaded program flow; the compiler does not have any idea of concurrent processes. Even less does it make assumptions on the underlying hardware.
For all other variables, the compiler may (gcc for instance actually will) assume it has full knowledge about the system state.
Also accesses to volatile
variables may not be reordered with respect to each other. This is important when e.g. a UART requires the status register to be read first and then a new char may be stored to the transmit data register. For most MCUs, only this sequence will clear the flags properly. Very important: non-vloatile variables may be reordered as much as the compiler wants to (as long it does not change the program logic, of course).
Note that volatile
does not guarantee atomicity and correct behaviour on multicore-systems or does protect against re-ordering of accesses by the hardware (memory controller, etc.) (well, the AVR is a bit underprivileged with all these ;-). That is one reason for locks and why hardware-areas in the memory map are treated special by the hardware (ordered, non-shared).
Edit:
Here is detailed how gcc handles volatile objects. gcc is known to strictily keep to the standard for optimizations. Anything not forbidden might be exploited for optimization. Classic embedded compilers like IAR are often much more conservative.
回答3:
The C / C++ standard for volatile means that reads and writes to a volatile variable will be a read or write to that location in memory, and that the order of operations to a volatile variable will be maintained. Since reads from a volatile variable are actually reads of the variable in memory, then if the variable is updated by an outside source such as another thread, process, or hardware, the value read will reflect any writes that occurred before the read. It's meant to be used for memory mapped hardware interfaces such as I/O memory mapped ports. It doesn't prevent out of order operations on other variables. I assume that the order of operations on multiple volatile variables is maintained, since this would be needed for hardware / software handshake.
Microsoft compilers optionally extend the meaning of volatile so that read / write operations to volatile variables are effectively done as a memory barrier and can be use for communication between threads. MSDN volatile .
回答4:
volatile
, as you mentioned, is a guarantee that the compiler will perform no optimizations regarding the variable. If a variable's value isn't changed in a scope as determined by the compiler, it may cache the value to a register and refer to that cached value for efficiency so it doesn't waste cycles fetching the actual value from main memory.
I'd imagine in a microcontroller with such limited amounts of registers, you wouldn't want to cache variables constantly.
来源:https://stackoverflow.com/questions/30472561/volatile-keyword-in-microcontrollers