2016-07-05 43 views
3

我正在實現我自己的原子類,因爲在特定項目中我無法訪問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,因爲它正在被複制以供返回。

我已經看過在Visual Studio中對這樣的代碼進行反彙編,它似乎顯示返回調用之前析構函數被調用,但a)我真的不知道我是什麼看着大會(我還在學習:))和b)我不知道這是否是標準行爲(再次,我還在學習)。最安全的解決方法,以這種潛在問題是

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

...但如果這是矯枉過正,我寧願現在知道了。

+1

你在哪個平臺上?它們中的大多數都具有原子增量和獲取的內在性,您可以使用它來代替互斥鎖 – Dani

+0

這必須在Windows,Solaris Sparc和Linux上運行。我知道Windows上有原子遞增函數,但無法找到原子檢索函數,也無法訪問Solaris上的必需函數。因此,這個問題。 – Wad

+0

C++中沒有「寄存器」。該代碼是正確的書面。 –

回答

5

您的代碼是正確的。 [stmt.return]/3表示:

呼叫的結果的副本初始化是在全表達的通過返回語句,的操作數建立的端臨時對象的破壞之前測序,其,然後在 之前對包含return語句的塊的局部變量(6.6)進行銷燬。