简体   繁体   English

volatile关键字和RAII习语(C ++)

[英]volatile keyword and RAII idiom (C++)

assuming to have a class to control concurrent access to a (critical) code block similar to this one: 假设有一个类来控制与这个类似的(关键)代码块的并发访问:

class RAIIObj : public boost::noncopyable {
public:
    explicit RAIIObj( LockObj& Obj ) : LkObj( Obj ) { Obj.Acquire(); }
    ~RAIIObj() { try { Obj.Release(); } catch (...) {} }
private:
    LockObj& LkObj;
};

When using such piece of code, do I need to use volatile keyword in order not to see the code be optimized away? 使用这样的代码时,我是否需要使用volatile关键字才能看到代码被优化掉?

For example, do I have to write 例如,我必须写

ALockingObj LockObj;

void AFunc() {
    RAIIObj LKGuard( LockObj );

    // do some MT stuff
}

or 要么

ALockingObj LockObj;

void AFunc() {
    volatile RAIIObj LKGuard( LockObj );

    // do some MT stuff
}

in order to be sure that LKGuard always exists? 为了确保LKGuard始终存在?

As LKGuard is a local variable that is not used at any point in the body of the function, could be optimized away if I do not use the volatile keyword? 由于LKGuard是一个局部变量,在函数体的任何一点都没有使用,如果我不使用volatile关键字,可以优化掉吗?

Thanks 谢谢

no you dont need to declare it volatile. 不,你不需要声明它不稳定。 The compiler can see that instantiating lkobj does a whole bunch of stuff that cant be optimized out (as opposed to int lkobj; which clearly does nothing) 编译器可以看到实例化lkobj做了一大堆无法优化的东西(与int lkobj;它显然什么都不做)

While the answer provided by pm100 is indeed correct as far as the standard is concerned, I discovered that GCC 4.9 can optimize RAII types away (optimization flags: -Os -flto ). 虽然pm100提供的答案在标准方面确实是正确的,但我发现GCC 4.9可以优化RAII类型(优化标志: -Os -flto )。 This is the code I had that the optimizer was throwing away: 这是优化器丢弃的代码:

class MutexLocker
{
    chibios_rt::Mutex& mutex_;
public:
    MutexLocker(chibios_rt::Mutex& m) : mutex_(m)
    {
        mutex_.lock();
    }
    ~MutexLocker()
    {
        mutex_.unlock();
    }
};

Making the type volatile solved the problem: 使类型volatile解决了问题:

namespace impl_
{
    class MutexLockerImpl
    {
        chibios_rt::Mutex& mutex_;
    public:
        MutexLockerImpl(chibios_rt::Mutex& m) : mutex_(m)
        {
            mutex_.lock();
        }
        ~MutexLockerImpl()
        {
            mutex_.unlock();
        }
    };
}
using MutexLocker = volatile impl_::MutexLockerImpl;

Therefore, despite the fact that the standard does not require that, I would suggest to explicitly declare RAII types volatile in order to account for aggressive optimization. 因此,尽管标准不要求这样做,但我建议明确声明RAII类型是易失性的,以便考虑积极的优化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM