Today I Learned that in C++, the volatile qualifier can be used not only for variables but also for member functions of a class. This is done in the same way as the const qualifier, by placing it after the function’s parameter list. For example:

class MyClass {
public:
    void myFunction() volatile {
        // This function can be called on volatile instances of MyClass
    }
};
It works similarly to const member functions, which can be called on const instances of a class. A volatile member function can be called on volatile instances of the class. This is mostly relevant for low-level code, such as memory-mapped I/O or hardware-facing interfaces. A volatile member function can call other volatile member functions. However, it cannot call non-volatile member functions on the same object, because inside such a function this is treated as a pointer to a volatile object. Data members do not need to be declared volatile individually: when they are accessed through a volatile object, those accesses are treated as volatile.
class MyClass {
public:
    void myFunction() volatile {
        // Access goes through a volatile object
        myMember = 42; // OK
        anotherVolatileFunction(); // OK
        // nonVolatileFunction(); // Error: cannot call non-volatile member function from volatile context
    }
    void anotherVolatileFunction() volatile {
        // Another volatile member function
    }
    void nonVolatileFunction() {
        // This function cannot be called on volatile instances of MyClass
    }
private:
    int myMember;
};

This feature is mostly useful in embedded systems and other low-level code, where an object may represent hardware state or memory-mapped registers. It is important to note that volatile does not provide synchronization, atomicity, or thread-safety guarantees. In C++, it is not a replacement for atomics or mutexes and should not be used for inter-thread communication.

To summarize, the volatile qualifier can be applied to member functions the same way as const. It affects which objects the function may be called on and how this is qualified inside the function. It is a niche but valid feature, mostly relevant in embedded systems and low-level programming.

“Live as if you were to die tomorrow. Learn as if you were to live forever.” - Mahatma Gandhi