Lets suppose it is embedded development of some ARM controller. Lets suppose we have some variable, which can be assigned from an interrupt or "mainThread" - (is it a "main loop" or RTOS thread). In C world volatile
keyword should be used in this case and code may look like this:
/* Some subsystem .C file */
static volatile uint8_t state;
void on_main_thread(void) {
state = 1; /* Changing state in this context */
}
void on_interrupt(void) {
state = 0; /* Changing state from interrupt */
}
uint8_t get_state(void) {
return state; /* Getting the state in whatever context */
}
volatile
keyword is essential in this situation. Now our company rewrites some code to C++ and the same subsystem example looks like this (I use enum here to emphasize the problem)
class SomeSubsystem
{
public:
enum class States
{
Off,
Idle,
Up,
Down,
};
States getState() const { return mState; }
void onMainThread(void) {
mState = States::Idle; // Changing state in this context
}
// Somehow this function is called from the interrupt
void onInterrupt(void) {
mState = States::Up; // Changing state from interrupt
}
private:
States mState; // <-- Here! Volatile?
//...
};
Now States mState
should be volatile because it is shared among different contexts. But If one sets it as volatile... Then volatile
works like plague for C++ class and one have to volatilize everything around. Like volatile enum class States
, getState() volatile
etc. Which doesn't look good for me (am I wrong?)
So. What is the right way to handle this situation in C++?
P.S. I would try to define "this situation" as: "possible usage of a class members from different contexts like interrupts and normal code execution"