私は最近、組み込みデバイスで C++ コードをいじり始めた組み込み C 開発者であり、クラスがメモリ マップド レジスタなどの揮発性データや、アナログ デジタル コンバーター (ADC)。
たとえば、次のように、ポインターを介してメモリにマップされたレジスタにアクセスすることにより、デバイスのハードウェア モジュールにインターフェイスするクラスがあります。
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_;
};
もちろん、レジスタ名は例のために作成されています。興味のある方のために、Microchip PIC32 デバイスを使用しています。
私のおそらく間違った理解からすると、メソッドをマークするconst
ということは、呼び出し元に関する限り、オブジェクトの監視可能な状態が変化してはならないことを意味します。いつでも変更される可能性のあるデータにアクセスし、呼び出し元が変更を監視するため、ReadIOState()
メソッドはそうすべきではありませんか? それとも、メソッドが明示的に何も変更していないためでしょうか?const
volatile
const
const
現在、質問に記載されている理由により、その方法を作成しない方向に傾いています。これは、このGotWの記事に出くわした後、特に当てはまりますconst
. const
私の組み込みアプリケーションはシングル スレッドですが、一般的なネスの良いリトマス試験紙になると思います。
また、コンパイラはメソッドをどのように扱いconst
ますか? つまり、次のように IO の状態をポーリングするとどうなりますか。
// wait for IO pin to go high
while(!myIOpin.ReadIOState())
{}
ReadIOState()
がの場合const
、コンパイラは 1 回の呼び出しの後に返された値を再利用できvolatile
ますか?それとも、データにアクセスしていることを確認してそれを行わないほど賢いでしょうか?