2010-03-21 28 views
28

當我做: less /usr/include/stdio.h(這是隻有一個C庫 - 無關C++)爲什麼我在C庫中看到THROW?

我看到__THROW不少函數聲明之後。 此外,上面的幾個功能的評論說'這個功能是一個可能的取消點,因此不標記__THROW' 這是什麼?

throw是爲了異常處理......但據我所知,C不提供任何支持。

請解釋。

+1

哪個編譯器?看起來像我的GCC。 (請記住,沒有「標準庫」,因此指定您使用哪種實現方式會很有幫助。) – GManNickG

+1

啊,我發現你已經發現了glibc :) –

回答

34

此標頭可能在該供應商的C和C++編譯器之間共享。你看過什麼__THROW被定義爲?

我懷疑一個類似於:

#ifdef __cplusplus 
    #define __THROW throw() 
#else 
    #define __THROW 
#endif 

或者實際規格:

#ifdef __cplusplus 
    #define __THROW(x) throw(x) 
#else 
    #define __THROW(x) 
#endif 

正如你可以看到,在C構建,它什麼也不擴展。在C++中,它符合你的期望。這允許供應商重複使用相同的文件。


只是雞蛋裏挑骨頭,這是不完全正確的:「(這是唯一一個C庫 - 沒什麼用C++做++)」

C++標準庫包括使用的能力C標準庫。實際標頭爲<cxxx>,其中xxx是C標頭名稱。也就是說,要在C++中包含C頭<stdlib.h>,你需要做<cstdlib>。所以它確實與C++有關。 :)

這就是爲什麼你看到你所做的代碼。複製兩種不同語言的標題將是維護和清潔的噩夢。

+0

感謝你的回答非常有幫助。 –

3

要回答您有關「此函數是一個可能的取消點,因此不用__THROW標記」的其他問題:這涉及多線程。你可以「取消」一個線程,但它不會「取消」,直到到達取消點。一些更多的信息:http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

+0

鏈接已損壞。 –

+0

謝謝。完全更改爲另一個鏈接,仍然提供有用的信息。 – Ioan

2

你可以做

cpp -include stdlib.h -dM /dev/null |grep '#define __THROW ' 

學習它實際上擴大到。

在我的系統,我得到:

#define __THROW __attribute__ ((__nothrow__ __LEAF)) 

拋出異常屬性在 https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes 描述如下:

使用此屬性調用外部函數時,只能通過返回或異常處理返回到當前編譯單元的 。 特別是,一個葉函數不允許調用回調函數 從當前編譯單元傳遞給它的函數,直接調用 函數調用單元導出的函數,或者將longjmp導入到單元中。葉 功能可能仍然調用其他編譯單元和 功能,因此它們不一定是葉,因爲它們根本不包含 函數調用。該屬性旨在用於庫函數 以改進數據流分析。編譯器會提示不能轉義當前編譯單元的任何數據,也不能使用葉函數修改 。例如,sin函數是一個葉函數,但qsort不是。

請注意,葉函數可能間接運行使用靜態變量的當前編譯單元中定義的信號處理程序 。類似地,當惰性符號解析有效時,葉函數可能調用 的間接函數,其解析器函數或實現函數 在當前編譯單元中定義並使用靜態變量。 沒有標準兼容的方式來編寫這樣的信號處理程序, 解析器函數或實現函數,並且您最好能夠執行的操作是刪除葉子屬性或將所有這些靜態變量標記爲易失性的 。最後,對於支持符號 插入的基於ELF的系統,應注意當前編譯單元中定義的函數不會意外地根據定義的標準模式和定義的特性測試宏插入其他符號 ; 否則會添加無意的回調。

該屬性對當前編制單位中定義的功能沒有影響。這樣可以簡化多個編譯單元的合併,例如,通過使用鏈接時間 優化。因此,該屬性不允許在 註釋間接調用的類型上使用。

拋出異常

拋出異常的拋出異常屬性用於以通知 函數不能拋出異常的編譯器。例如, 標準C庫中的大多數函數都可以保證不會拋出異常,並且 是qsort和bsearch的顯着例外,它們使用函數指針 參數。

什麼__attribute__((nothrow))意味着在C被回答在gcc - what is attribute nothrow used for?。基本上,它用於與C++代碼的合作,如果函數不會回調異常拋出的C++代碼,則可以使用它。

相關問題