簡體   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