2014-06-23 79 views
20

我找不到標準中強制使用extern "C"聲明的函數爲noexcept的任何內容,無論是隱式還是顯式。C++標準要求C連接函數是否爲「noexcept」?

但是,應該清楚的是,C調用約定不能支持異常......或者它是什麼?

標準是否提到了這個,我錯過了什麼地方?如果不是,爲什麼不呢?它是否僅僅作爲各種實現細節而留下?

+0

無法想象在C++語言進化中這種兼容性的規模會突破,我們可以嗎? – Sheen

+2

它是否會破壞兼容性,這是相當可疑的。從C函數泄漏異常的程序可能始終存在未定義的行爲。 – Puppy

+4

相關http://stackoverflow.com/a/15845731/242520 –

回答

17

據我所知,不能保證用「C」連接定義的函數不會拋出異常。該標準允許C++程序既可以調用具有「C」語言鏈接的外部函數,也可以定義具有「C」語言鏈接的用C++編寫的函數。因此,沒有什麼可以阻止C++程序調用實際上用C++編寫的「C」語言鏈接的函數(在另一個編譯單元中,也許,儘管這不是必要的)。這將是一件很奇怪的事情,但很難排除。我也沒有看到它在標準中的位置,它表示這樣做會導致未定義的行爲(事實上,因爲標準不能定義不是用C++編寫的函數的行爲,這隻會是只有用法,其中沒有正式的未定義的行爲)。

因此,我認爲假設「C」連接意味着noexcept將是錯誤的。

+1

好的答案,你當然知道如何用正確的方式說話。 – didierc

+2

一個不太奇怪的情況是接受(並調用)函數指針的C函數,它可能指向拋出的C++函數。 –

8

恩,我假設extern "C"只是使用C-linkage,而不是C函數。它阻止編譯器執行C++ name mangling

更直接 - 假設這段代碼。

// foo.cpp 
extern "C" void foo() 
{ 
    throw 1; 
} 

// bar.cpp 
extern "C" void foo(); 
void bar() 
{ 
    try 
    { 
     foo(); 
    } 
    catch (int) 
    { 
     // yeah! 
    } 
} 
+1

實際上,除了防止名稱變形之外,還有更多。 'extern「C++」void Foo();'不同於'extern「C」void Foo();'。它們是不同的**類型**,並且具有不同的屬性,鏈接僅僅是其中之一。 –

+1

我認爲它也會影響調用約定,並且異常需要特定的調用約定才能使堆棧展開工作。 –

相關問題