C++;具有易失性和外部数据访问的常量正确性 我是一个嵌入式C开发人员,最近在嵌入式设备上开始使用C++代码,当类访问诸如内存映射寄存器或外部设备上的数据(如模数转换器(ADC))等易失性数据时,不确定const正确性是如何应用的。
例如,我有一些类,它们通过指针访问设备的内存映射寄存器,从而与设备的硬件模块进行接口,如下所示:C++;具有易失性和外部数据访问的常量正确性 我是一个嵌入式C开发人员,最近在嵌入式设备上开始使用C++代码,当类访问诸如内存映射寄存器或外部设备上的数据(如模数转换器(ADC))等易失性数据时,不确定const正确性是如何应用的。,c++,embedded,const-correctness,C++,Embedded,Const Correctness,例如,我有一些类,它们通过指针访问设备的内存映射寄存器,从而与设备的硬件模块进行接口,如下所示: class IOPin { public: /* Constructor, destructor, other methods...*/ // should this be a const method? bool ReadIOState() {return portregs_->state;} private: /* Other private stuff
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_;
};
注册名称当然是为了举例而编造的。我正在为好奇的人使用一个微芯片PIC32设备
根据我可能不正确的理解,标记方法const
意味着对象的可观察状态就调用方而言不应该改变。因此,ReadIOState()
方法不应该是const
,因为它访问的volatile
数据在任何时候都可能发生变化,因此调用者会观察到变化?或者应该是const
,因为该方法没有显式更改任何内容
目前,出于问题中所述的原因,我倾向于不使用该方法const
。这一点在绊倒之后尤其如此,它表明const
的意思正在变为“能够同时阅读”。我的嵌入式应用程序是单线程的,但我认为这可能是对const
ness的一个很好的试金石测试
另外,编译器如何处理const
方法?也就是说,当我想像这样轮询IO的状态时会发生什么:
// wait for IO pin to go high
while(!myIOpin.ReadIOState())
{}
如果
ReadIOState()
是const
,那么编译器是否可以重用一次调用后返回的值,或者它是否足够聪明,可以看到它正在访问volatile
数据而不这样做?您只是在类中有指向结构的指针,并且不更改指针,因此方法可以是const。编译器不应该重用上一次调用中的值,它已经足够聪明了。我想知道您是否可以像创建const methods那样创建volatile方法。void test()volatile{}在VS2012上编译,但我不知道这意味着什么,因为我以前从未使用过volatile。@NeilKirk是的,您可以这样做。这意味着可以在volatile
实例上调用该函数。就像const
函数可以在const
实例上调用一样。如果你愿意,你甚至可以拥有一个成员函数的所有4个重载。这些评论让我意识到我必须考虑如何在中断例程中使用C++对象。它们中使用的变量通常声明为volatile,尽管我不确定这如何适用于我正在调用其方法而不是直接访问成员的对象。感谢您的响应!这是真的,我一直在提醒自己,指针本身才是常量。然而,我认为我的问题更多的是哲学方面的。也就是说,对一个方法使用const是否意味着该方法的返回值?如果返回值可以在对方法的两次连续调用之间更改,即使该类不是更改它们的人,那么说它是const有意义吗?const是仅在编译时使用的关键字,在运行时不执行与const相关的特殊检查(只有在有运气和const值的情况下才被存储在只读内存页中),这个关键字只用于编译时从编译器获得更多帮助(编译错误)。使用const方法并不意味着任何方法的返回值。这是C++中不太直观的一面。