As in the question: let's say I have a small piece of code like this:
#include <iostream>
using namespace std;
struct foo {
int a;
foo() : a(12) {};
};
int
main()
{
volatile foo x;
return 0;
}
compiled with g++ -g -O2
it turns out, that x
initialization is optimized away.
That one however:
#include <iostream>
using namespace std;
struct foo {
volatile int a;
foo() : a(12) {};
};
int
main()
{
volatile foo x;
return 0;
}
calls the constructor.
If I try to use the variables inside the code, (ie. cout << foo.a << endl;
) the assembly output is equivalent in both cases.
Do I get the following right, that:
In the first case, there's no access to the struct at all, so it gets optimized away completely.
In the second one, struct's field is indicated as the one possible to change also during the construction and for that reason foo() is called no matter what.
Added:
I've tried fiddling with the above code:
calling things like while(foo.a--);
works as expected, it actually happens instead of being deleted/replaced by result during optimization, thus it seems the volatile is actually inherited, yet the ctor behaves in this strange (or at least unexpected at first) way.
EDIT number 2:
I checked it with clang and MSVC and it behaves the same way as in gcc.
C's volatile keyword is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change at any time--without any action being taken by the code the compiler finds nearby.
non volatile means that your current compiler decides where the variable will be located or how the variable-s value is teransfered to a subroutine.
The volatile keyword is intended to prevent the compiler from applying any optimizations on objects that can change in ways that cannot be determined by the compiler. Objects declared as volatile are omitted from optimization because their values can be changed by code outside the scope of current code at any time.
Volatile Keyword means that the variable will be loaded from its memory location every time you are using this variable, the compiler will never depend on the temporary value stored in the internal CPU Registers.
My understanding is as follows (and I am not sure about it):
In C++ volatile
keyword forces compiler not to optimize seemingly redundant loads and stores to memory, i.e. if you have such example code:
int x = 5;
x = 6;
It will not be changed to:
int x = 6;
This is because x
could be pointing to some address in memory, that is read by others, while you don't read it really in your program (imagine that you are sending some configuration over USART to microcontroller by writing to certain memory address, and the microcontroller reads it's configuration from that address - if compiler was to optimize writes to this memory, then whole program would malfunction).
Another thing that one must remember is that when instance of a class is declared with volatile
specifier, then its members inherit this specifier (as Igor Tandetnik pointed out in comment, referring to C++ Standard). But this is not the whole truth, because in order to get volatile
behaviour, you would have to call member functions, that are marked as volatile
- similar to marking member function as const
(please see this: http://www.devx.com/tips/Tip/13671). Because AFAIK ctors/dtors cannot be marked with volatile
keyword (as in Defining volatile class object), you would have to change your code a bit (perhaps invoking volatile member function from within ctor would do the thing, but this is only a guess).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With