C++ 具有易失性和外部数据访问的常量正确性

问题描述 投票:0回答:2

我是一名嵌入式 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()
方法 not 是否应该是
const
因为它访问可能随时更改的
volatile
数据,因此调用者会观察到变化?或者应该是
const
因为 方法 没有明确改变任何东西?

目前,由于问题中所述的原因,我倾向于不采用该方法

const
。在偶然发现这篇 GotW 文章之后尤其如此,其中指出
const
的含义正在更改为“能够同时阅读”。我的嵌入式应用程序是单线程的,但我认为这可能是总体上
const
性的一个很好的试金石。

另外,编译器如何处理

const
方法?也就是说,当我想像这样轮询 IO 的状态时会发生什么:

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

如果

ReadIOState()
const
,那么编译器是否可以重用一次调用后返回的值,或者它是否足够聪明,可以看到它正在访问
volatile
数据而不这样做?

c++ embedded const-correctness
2个回答
2
投票

您只是拥有指向类内部结构的指针,并且没有更改指针,因此该方法可以是 const。编译器不应该重用之前调用的值,它足够聪明。


0
投票

它应该是常量。

让我们找一个由 C++ 标准类访问外部状态的情况。

system_clock::now() 不是 const,steady_clock::now().

读取时钟与读取寄存器非常接近。事实上,steady_clock有时是通过读取CPU寄存器来实现的,该寄存器包含自启动以来的周期数。

如果 C++ 标准类未将寄存器读取方法标记为

const
,您的类也应该这样做。

© www.soinside.com 2019 - 2024. All rights reserved.