Search code examples
c++embeddedvolatile

C++ reference to volatile object - reasons and effects


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?


Solution

  • 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".