2016-09-29 68 views
0

P0012R1,「進行異常規格類型系統的一部分」,
我看到noexcept正在成爲功能型的一部分。noexcept函數是否仍然可以調用一個拋出C++ 17的函數?

我不能說這是否會阻止noexcept(true)函數仍然能夠調用noexcept(false)函數。

以下代碼對於C++ 17仍然有效嗎?

void will_throw() noexcept(false){ 
    throw 0; 
} 

void will_not_throw() noexcept(true){ 
    will_throw(); 
} 
+0

如果throwing函數在noexcept函數中的'try ... catch'內,該怎麼辦? –

+4

'noexcept'意味着一個函數_will_不會拋出,而不會拋出,而不遵守的懲罰是調用'std :: terminate',而不是UB。所以是的,該代碼是合法的。 – ildjarn

回答

4

根據cppreference

需要注意的是在功能的noexcept規範不是編譯時 檢查;它僅僅是一種程序員通知編譯器 函數是否應該拋出異常的方法。

所以你的代碼的語法是有效的,但執行時會調用std::terminate

0

包括功能類型異常規範正交函數是否可以調用與不兼容的異常規範另一個功能(不處理對在其異常規範包括在例外)。前者關於函數指針的類型安全性(這樣你就不能通過已知不會拋出的函數指針來調用拋出函數)。關於後者,我們可以在編譯過程中禁止它(如Java),或者將其視爲運行時錯誤(導致終止程序,就像C++當前標準所選擇的那樣)。

可以通過使用const(非靜態)成員函數調用非const(非靜態)成員函數的類比來爭論。然而,不同之處在於,間接修改通過const成員函數調用的非const成員函數內的對象將不會被檢測到(否則將花費太高而無法檢測到),並且可能導致令人討厭的錯誤,這就是爲什麼它必須在彙編。鑑於拋出異常的行爲是(應該是)異常事件,並且我們可以負擔插入運行時檢查異常是否符合異常規範並且應該被放出,或者它違反了程序邏輯並且應該終止程序。

0

noexcept(true)函數可以調用noexcept(false)函數。如果拋出異常,將會出現運行時錯誤。爲什麼這是允許的典型的例子是:

double hypotenuse(double opposite, double adjacent) noexcept(true) 
{ 
    return std::sqrt(opposite*opposite + adjacent*adjacent); 
} 

std::sqrt將拋出domain_error如果參數爲負,但顯然永遠不會在這裏。 (在理想的情況下,默認情況下,exception_cast允許在需要的地方允許它,如果拋出異常,或者std :: terminate,結果可以是UB)。

相關問題