返回值寄存器和析构函数调用顺序

时间:2016-07-05 19:07:45

标签: c++ multithreading

我正在实现我自己的原子类,因为在一个特定的项目中,我无权访问C ++ 11原子库。到目前为止,我有以下代码:

 class CAtomicLong
 {
 public:

     CAtomicLong(long lVal) : m_lValue(lVal) {}

     long operator+(long lVal)
     {
         CAutoLock lock(m_lock);
         m_lValue += lVal;
         return m_lValue;
     }
 private:

     CMyMutex m_lock;
     long m_lValue;
 };

假设CMyMutex是围绕互斥锁的自定义包装器,CAutoLock是一个类,其析构函数解锁在构造期间传递给它的对象。无论如何,这些细节在很大程度上与这个问题无关。

我想知道的是,如果这样返回m_lValue是安全的;也就是说它会被复制到一个寄存器中,以便在调用lock的析构函数之前返回?我问,因为我担心撕裂的读取和写入,因为如果在之前调用析构函数,则设置返回寄存器,另一个线程可以在复制它时开始修改m_lValue。< / p>

我已经看过Visual Studio中的反汇编这样的代码,它似乎显示在调用析构函数之前返回调用但是a)我真的不知道我正在看装配(我还在学习:))和b)我不知道这是否是标准行为(再次,我还在学习)。此潜在问题最安全的解决方法是

long operator+(long lVal)
{
    CAutoLock lock(m_lock);
    long lTemp = (m_lValue += lVal);
    return lTemp;
}

......但如果这有点矫枉过正,我现在就知道了。

1 个答案:

答案 0 :(得分:6)

您的代码是正确的。 [stmt.return] / 3说:

  

调用结果的复制初始化在由return语句的操作数建立的完整表达式结束时临时销毁之前进行排序,而后者又在之前被排序。   包含return语句的块的局部变量(6.6)的破坏。