我有脑痉挛:
struct MyStruct
{
int x;
...
inline int getX1() const { return x; }
inline int getX2() const volatile { return x; }
};
volatile MyStruct myStruct;
我知道编译器会让我调用myStruct.getX2()并且不会让我调用myStruct.getX1()
,因为在volatile结构/类上调用的方法必须在这些方法上有volatile
限定符
这是我的问题:如果我创建了这样一个类,并将其发布以供其他软件例程使用,那么我将添加或不在方法上添加volatile限定符的原因是什么?
是否因为标记为volatile
的方法告诉编译器不要假设其成员不是volatile
,以进行优化,而如果方法没有标记volatile
,那么任何未标记为volatile
的成员都可以进行优化?
答案 0 :(得分:3)
标准不为任何标准类提供volatile
成员函数,因此在正常情况下也不应该。
你对最后一段中的含义是正确的 - 就像const
成员函数一样,在volatile
成员函数this
中是一个指向易失性的指针。因此无论您的实现如何实现易失性存储器访问(禁用各种优化,对于初学者),它都将通过this
进行任何访问。
我怀疑为一个包含一些内存的类提供volatile
成员函数是值得的,这些内存可能实际上是易失性的,或者可能不是。然后,用户可以根据需要创建volatile
或非volatile
对象。如果内存肯定是需要是易变的,那么我认为你最好使用具有volatile
数据成员的非volatile
对象。
现在我试图想象一个真正的用途 - 一个“计数器”类可以在魔术地址的顶部创建,该地址由硬件或你写的中断更新(在这种情况下你可以使用placement new创建一个volatile实例,但也有一个用例,它只能通过“普通”代码的调用进行更新(在这种情况下,它可以是一个非易失性实例)。在两种情况下,你可能只是采取使数据成员易失的“性能损失”,因为它没有其他危害。但是你可以提供成员函数的volatile
和非volatile
版本,包含相同的代码,其中一个将被优化而另一个不会。
答案 1 :(得分:1)
是否因为标记为volatile的方法告诉编译器不要假设其任何成员不是volatile,出于优化目的,而如果方法没有标记为volatile,那么任何未标记volatile的成员都可以进行优化?
是
在volatile
函数中,*this
对象变为volatile
,这反过来意味着该类的每个非静态成员都变为volatile
,就像在{const
中一样1}}函数,*this
对象变为const
,这反过来意味着该类的每个非静态成员都变为const
。
已经说过编译避免积极地优化涉及volatile
函数中成员的代码。