C++ is very strong in every aspect of modern programming. Volatile types are used with the volatile
keyword. It is a lesser known type qualifier that is important to read types or objects whose value can be modified at any time. The volatile keyword is useful in memory-mapped applications, generally these are from a hardware device, from a sensor, from an input device, or data from on an IoT. For example, an application reading dynamic data from the registers of a medical robot and decides what to do with that robot arm. In this post we will explain the volatile keyword in C++ and how can we use volatile type specifier.
What is volatile keyword in C++?
Volatile types are declared with the volatile
keyword with a type declaration. Here’s how it is used.
1 2 3 |
volatile <type> <type_name>; |
We can use volatile on standard types, structs, unions. We can use them with pointers too. Here are some examples of how to use the volatile
keyword in C++.
1 2 3 4 5 |
volatile int x; volatile unsigned long int *p; |
The volatile
type specifier is used to change the variable whose values can be changed at any time and don’t have any constant value. The volatile qualifier is important to prevent the compiler from applying any optimizations on objects that can change in ways that cannot be determined by the compiler. Generally used in loops to read data, if you read those kinds of data without volatile
types, the compiler and its optimizer can see the loop as useless. Your loop will never read the exact data in that time.
For example, in this example:
1 2 3 4 5 6 7 8 |
unsigned int x = 255; do { // ... }while( x == 255 ); |
compiler optimization covert this as below:
1 2 3 4 5 6 7 8 |
unsigned int x = 255; do { // ... }while( true ); |
In other words, our loop becomes infinite by being true always even if the value of x
is changed in some steps inside. To solve this, we can use volatile
, thus we will keep reading data from x in do-while loop. Here is the example,
1 2 3 4 5 6 7 8 |
volatile unsigned int x = 255; do { // ... }while( x == 255 ); |
If you want to keep reading x data from that address, you must use volatile
specifier for the x
type.
This is why the volatile
specifier is needed when developing embedded systems or device drivers. If we need to read or write a memory-mapped hardware device, we can use volatil
e type specifier on these kinds of data. Because data on that device register could change at any time, so we need to use volatile
keyword to ensure that we read data on that time and such accesses aren’t optimized away by the compiler.
Another need is some processors have floating point registers that have more than 64 bits of precision and if you need consistency then you can force each operation to go back to memory by using the volatile
keyword.
Volatile specifier is also useful for some algorithms, such as Kahan summations, etc.
Is there an example to use volatile keyword in C++?
Assume that we have an address in our device or in a library of a driver, let’s set this address to a volatile p
variable and let’s check it in a loop. Here is a simple example,
1 2 3 4 5 6 7 8 9 10 11 12 |
void wait_input() { volatile uint16_t* p = KNOWN_ADDRESS_ON_A_DEVICE; do() { }while ( *p != 100) // keep reading exact data from this pointer adress } |
Can we use volatile keyword in C++ multi-threading?
The volatile
type specifier is mostly useless for multithreaded, platform-agnostic applications. It does not make operations atomic, doesn’t provide any synchronization, doesn’t create memory fences, nor does it ensure the order of execution of operations. It can be used to help the compiler when accessing some shared resource in a non-protected way. Since C++11, volatile
is still not a synchronization mechanism, using volatile
for threading is not recommended in general.
C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.
Design. Code. Compile. Deploy.
Start Free Trial
Free C++Builder Community Edition