Уничтожены ли местные жители до или после вычисления возвращаемого значения функции?

Я думаю о создании класса, который представляет владение примитива синхронизации, что-то вроде этого:

class CCriticalSectionLock
{
public:
CCriticalSectionLock( CCriticalSection &cs ) : cs( cs )
{ cs.Enter(); }
~CCriticalSectionLock()
{ cs.Leave(); }
private:
CCriticalSection &cs;
};

Это выглядит как хороший способ получить право собственности во время выполнения функции и обеспечить освобождение владельца, даже если существует несколько точек выхода или исключений. Это, однако, поднимает некоторые тонкие вопросы о том, когда именно компилятор будет оценивать различные вещи. Рассмотрим следующее использование:

int MyMethod( void )
{
not_locked(); // do something not under lock

CCriticalSectionLock myLock( someCriticalSection );

locked(); // do something under lock

return ...; // some expression
}

AFAIK, правила жизни C ++ гарантируют, что not_locked() будет называться до замок взят, и это locked() будет вызван, пока блокировка удерживается.

Тем не менее, я не совсем понимаю, когда именно будет вычислено возвращаемое выражение. относительно точки, в которой вызывается деструктор блокировки. Гарантируется ли, что выражение будет оценено до деструктор? Я бы так подумал, но я не уверен на 100%, и в противном случае это может привести к очень тонким, прерывистым, труднодоступным ошибкам!

7

Решение

Если бы они не были, это было бы очень проблематично.

Действительно, рассмотрим следующий код:

int function(){

MyClass myObject;
//stuff
return 5 + myObject.getNumericalValue();
}

с getNumericalValue() простая функция-член, которая возвращает int на основе вычислений для переменной-члена. Если выражение было оценено после уничтожения myObject, вы бы имели неопределенное поведение, и использование локальных операторов было бы невозможно в выражении return (что не так).

В вашем случае замок будет разрушен после оценка возврата заявления.

Чтобы добавить к этому некоторую строгость, позвольте мне процитировать стандарт (§3.7.3 / 3, выделение мое):

Если переменная с автоматической продолжительностью хранения имеет инициализацию или деструктор с побочными эффектами, это не должно
быть уничтоженным до конца своего блока
, и при этом это не должно быть устранено как оптимизация, даже если это кажется
быть неиспользованным

Конец блока для функции после ответное заявление.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]