我正在考虑创建一个代表同步原语所有权的类,如下所示:
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().
但是,我不太清楚的是,何时返回的表达式将根据调用锁析构函数的点进行计算.是否保证在析构函数之前计算表达式?我会这么认为,但我不是百分百肯定,如果不是,它可能导致非常微妙,间歇性,难以发现的错误!
解决方法
如果他们不是,那将是非常有问题的.
确实,请考虑以下代码:
int function(){ MyClass myObject; //stuff return 5 + myObject.getNumericalValue(); }
getNumericalValue()是一个简单的成员函数,它根据成员变量的计算返回一个int.如果在销毁myObject之后计算表达式,则会有未定义的行为,并且在return语句中使用locals是不可能的(事实并非如此).
在您的情况下,锁定将在评估return语句后销毁.
为了增加一些严格性,让我引用标准(§3.7.3/ 3,强调我的):
If a variable with automatic storage duration has initialization or a destructor with side effects,it shall not
be destroyed before the end of its block,nor shall it be eliminated as an optimization even if it appears to
be unused
对于函数,块的结尾位于return语句之后.