繁体   English   中英

从std :: call_once中抛出异常

[英]Throwing an exception from std::call_once

C ++标准声明了以下关于std::call_once的执行以及抛出异常的函数(§30.4.4.2/ 2):

2 /效果:不调用其func的call_once的执行是被动执行。 调用其func的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)互联网在忙碌时被毁坏了

这应该发生吗?

这应该发生吗?

不,不是真的。 这是一个错误

但是,请注意VC11并不是唯一的事实:

  • 英特尔ICC 13.0.1调用std::terminate()就像没有处理您的异常一样(参见实例 );
  • GCC 4.8.0 beta可能会做类似的事情,但它没有显示任何输出,它只是吞下异常并静默终止程序(参见实例 )。 [ 更新:此错误似乎在其他环境中不可重现,并且可能只是在liveworkspace.org上的配置问题 ]

另一方面,GCC 4.7.2和Clang 3.2表现正常。

顺便说一句,值得注意的是C ++标准(第18.8.1节)指定std::exception 只有一个默认构造函数和一个复制构造函数 您正在使用的构造函数很可能是非便携式MS扩展。

您可以考虑使用std::logic_error ,它派生自std::exception并支持接受字符串的构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM