I'm an embedded C developer who has recently started messing with C++ code on an embedded device and am unsure about how const-correctness applies when a class accesses volatile data such as memory-mapped registers or data on an external device, such as an Analog-to-Digital Converter (ADC).
For example, I have classes that interface to the device's hardware modules by accessing its memory-mapped registers through a pointer, like so:
class IOPin
{
public:
/* Constructor, destructor, other methods...*/
// should this be a const method?
bool ReadIOState() {return portregs_->state;}
private:
/* Other private stuff...*/
// Constructor points this to the right set of memory-mapped registers
volatile struct portregs_t
{
uint32_t control;
uint32_t state;
uint32_t someotherreg;
} *portregs_;
};
The register names are of course made up for the sake of example. I'm using a Microchip PIC32 device for anyone who's curious.
From my possibly incorrect understanding, marking a method const
means that the observable state of the object should not change as far as the caller is concerned. So should the ReadIOState()
method not be const
because it accesses volatile
data that could change at any time and thus the caller would observe the change? Or should it be const
because the method isn't explicitly changing anything?
Currently, I am leaning towards not making that method const
for the reason stated in the question. This is especially true after stumbling upon this GotW article, which states that the meaning of const
is changing to mean "able to read concurrently". My embedded application is single-threaded, but I suppose that could be a good litmus test for const
ness in general.
Also, how does the compiler treat const
methods? That is, what happens when I want to poll the state of the IO like this:
// wait for IO pin to go high
while(!myIOpin.ReadIOState())
{}
If ReadIOState()
is const
, then can the compiler reuse the value returned after one call or is it smart enough to see that it is accessing volatile
data and not do that?
You are just having pointer to the struct inside the class and you do not change the pointer, so the method can be const. The compiler should not reuse the value from the previous call, it is smart enough.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With