C++ 标准规定了以下关于std::call_once
抛出异常的函数的执行(第 30.4.4.2/2 节):
2/ 效果:不调用其函数的 call_once 执行是被动执行。调用其函数的 call_once 的执行是主动执行。主动执行应调用 INVOKE (DECAY_COPY (std::forward(func)), DECAY_COPY (std::forward(args))...)。如果对 func 的这种调用引发异常,则执行异常,否则将返回。异常执行应将异常传播给 call_once 的调用者。在任何给定的 once_flag 的所有 call_once 执行中:最多一个应该是返回执行;如果有返回执行,则为最后一次主动执行;并且只有在返回执行时才会有被动执行。[注意:被动执行允许其他线程可靠地观察早期返回执行产生的结果。——尾注]
我正在使用 Visual Studio 2012 并运行以下代码:
void f(){
throw std::exception( "Catch me!" );
}
int main( int argc, char* argv[] ){
once_flag flag;
try{
call_once( flag, f );
} catch( const std::exception& e ){
cout << e.what() << endl;
}
return 0;
}
我的结果是:catch 块中的代码运行并打印消息,但是当程序存在时,我得到一个调用abort()
并将以下消息打印到 cout:
...\mutex.c(38) 互斥量在忙时被破坏
这应该发生吗?