6

私は最近、組み込みデバイスで 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()メソッドはそうすべきではありませんか? それとも、メソッドが明示的に何も変更していないためでしょうか?constvolatileconst

const現在、質問に記載されている理由により、その方法を作成しない方向に傾いています。これは、このGotWの記事に出くわした後、特に当てはまりますconst. const私の組み込みアプリケーションはシングル スレッドですが、一般的なネスの良いリトマス試験紙になると思います。

また、コンパイラはメソッドをどのように扱いconstますか? つまり、次のように IO の状態をポーリングするとどうなりますか。

// wait for IO pin to go high
while(!myIOpin.ReadIOState())
{}

ReadIOState()がの場合const、コンパイラは 1 回の呼び出しの後に返された値を再利用できvolatileますか?それとも、データにアクセスしていることを確認してそれを行わないほど賢いでしょうか?

4

1 に答える 1

2

クラス内の構造体へのポインターを持っているだけで、ポインターを変更しないため、メソッドは const にすることができます。コンパイラは、以前の呼び出しからの値を再利用すべきではありません。十分にスマートです。

于 2013-07-22T14:46:46.093 に答える