2016-07-05 4 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 для такого кода, и он показывает, что обратный вызов выполняется до деструктор вызывается, но: а) я действительно не знаю, что я глядя на сборку (я все еще учусь :)) и б) Я не знаю, является ли это стандартным поведением (опять же, я все еще участвую). Самый безопасный обходной путь для этого потенциала проблем

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

... но если это перебор, я предпочел бы знать сейчас.

+1

На какой платформе вы работаете? Большинство из них имеют встроенный прирост и выборку атома, который вы можете использовать вместо mutex. – Dani

+0

Это должно работать на Windows, Solaris Sparc и Linux. Я знаю, что в Windows есть атомарные функции инкремента, но не удается найти функцию атомного извлечения, и у меня нет доступа к требуемым функциям в Solaris. Отсюда этот вопрос. – Wad

+0

В C++ нет «регистров». Код правильный, как написано. –

ответ

5

Ваш код верен. [Stmt.return]/3 говорит:

Копия инициализация результата вызов секвенировал перед разрушением временных в конце полного выражения, установленного операндом оператора возврата, который , в свою очередь, секвенируется до уничтожение локальных переменных (6.6) блока, охватывающего оператор return.

Смежные вопросы