Reputation:
Given the following code:
struct Foo {
volatile int i;
};
const int& bar = foo.i;
I get:
error: invalid initialization of reference of type 'const int&' from expression of type 'volatile int'
Unless I provide a static_cast<volatile int>
.
Upvotes: 3
Views: 2349
Reputation: 254471
As with const
, a volatile
object can only be referred to by a volatile
reference. Otherwise, the compiler has no way of knowing that accesses to the object via the reference need to be volatile.
volatile const int& bar = foo.i;
^^^^^^^^
Unless I provide a
static_cast<volatile int>
It's rarely a good idea to silence a compiler error by adding casts. This doesn't give you a reference to foo.i
, but to a separate copy of it.
If you are doing something really strange that requires a non-volatile reference to a volatile object, you'd need const_cast
to remove the qualifer:
const int& weird = const_cast<int&>(foo.i);
Upvotes: 3
Reputation: 16824
"Volatility" of types in C++ works in pretty much exactly the same way as "const-ness" -- that is, an object that is volatile
cannot be assigned to a non-volatile
reference, in just the same way that
const int i = 3;
int& j = i; // won't work
Similarly, only methods marked volatile
can be called on a volatile object:
struct S
{
void do_something() volatile {}
void do_something_else() {}
};
volatile S s;
s.do_something(); // fine
s.do_something_else(); // won't work
Methods can be overloaded by "volatility", in the same way they can be overloaded by const-ness.
In C++ standardese, these things are known as cv-qualifiers, to emphasise that they work in exactly the same way. (C99 adds a third that works in the same way, restrict
, available as an extension in some C++ compilers). You can change cv qualifiers using const_cast<>
-- the more powerful static_cast<>
isn't required.
EDIT:
Just to make clear, a type can have both const
and volatile
modifiers at the same time, giving a total of four possibilities:
int i;
const int j;
volatile int k;
const volatile int l;
Upvotes: 7