I'm working on existing C++ code that has volatile
references to objects
volatile vClass & vobj;
I come from C
so I'm familiar with volatile
when used to access memory-mapped IO like this:
*((volatile unsigned int *) 0x12345678) = 0x5
QUESTION
What is the effect of applying volatile
to (a reference to) an object?
I would guess that all of its data members inherit volatile
but what about if a member function has non-volatile memory accesses like
void vClass::AccessMem() {*((unsigned int *) 0x12345678) = 0x5;}
Would that memory access too become volatile?
The member function must be volatile qualified to be called from a volatile object:
int not_a_member;
struct vClass {
int i;
void set(int j) {
i=j; //i is not accessed as a volatile
static_assert(std::is_same_v<decltype((i)),int&>);
}
void set_v(int j) volatile{
i=j; //here i is accessed as a volatile
static_assert(std::is_same_v<decltype((i)),volatile int&>);
not_a_member=j;//here not a volatile access because "not_a_member" is
// not a member.
//To understand what happen, since you are a C programmer it is going to be simple.
//The volatile qualifier is actualy apply to the "this" pointer,
// which is a pointer to the object from which this member function is
// called. So inside this function "this" as the type "volatile vClass"
//Inside a member function, all access to member data, as "i" are
//actualy short ends for "this->i". So in this access, "i"
//adopt the volatile qualifier of "this".
//So the volatile qualifier just applies to the data member of the object.
}
}
void use_vClass(){
volatile vClass x;
x.set(10); //Do not compile: "Error:try to access volatile object as non volatile"
x.set_v(10); //Compile
}
So since from a volatile object or reference, you can just call volatile qualified member function, all data member access will be "volatile".