2012-04-12 58 views
24

我只是想知道爲什麼名稱修改從未標準化的C++標準。很顯然,使用不同的名稱修改算法會影響互操作性[1],我認爲沒有實現定義的好處。爲什麼名稱修改不規範

也就是說,與調用約定或原語的大小相反,機器本身並不關心甚至不知道該函數是如何調用的。那麼爲什麼它不是標準化的,爲什麼它還沒有標準化呢?無論如何,編譯器在不同版本之間改變了規則。

[1]所有那些輸出功能爲extern "C"的人發言。

+11

標準化的名稱修改只會給您一種錯誤的安全感,因爲您還必須對ABI進行標準化才能獲得適當的互操作性。而C++標準委員會不太可能參與ABI標準化業務。 – 2012-04-12 16:46:12

+3

+1 @Raymond - 向你自己講述互操作性是個壞消息。這就像依靠未定義的行爲。當然,你認爲它有效,但它確實沒有。 – 2012-04-12 16:47:04

+0

沒錯,同意C++ ABI會比C更難。稍微OT:這個問題究竟是什麼被3人認爲不適合SO?畢竟,很明顯存在一個明確的答案,正如已經顯示的那樣。 – Voo 2012-04-12 17:00:53

回答

19

該標準沒有涉及實施細節。有很多東西取決於實現,並且阻止程序共同工作:如何佈置類,vtable的 結構等等。一般來說,編譯器會更改名稱如果它們改變改變任何這些。這是有意的,因爲它可以防止鏈接不起作用的代碼。

給定平臺可能定義C++ ABI;遵守它的所有編譯器 將使用兼容的實現,並且具有 通用名稱。然而,這對於平臺供應商來說是一個問題,然而, ;無論出於何種原因,很少有供應商定義了C++ ABI。

而原因extern "C"的工作原理是因爲幾乎所有平臺都定義了一個C ABI。

+2

應該補充的是,即使mangling被標準化,無論如何都需要extern」C「,因爲C不會做任何改動,而且C++必須支持重載函數,所以在任何情況下符號都是不同的。 – 2012-04-12 16:53:39

+3

@JanHudec它實際上並沒有很好地定義'extern「C」'的含義。例如,在沒有C編譯器的平臺上,這意味着什麼?然而,實際上,即使不是所有平臺都定義了C ABI,「extern」C也意味着堅持這一點。而且,在這裏,名稱不是唯一的問題;我曾經在C和C++之間將順序變量推入堆棧的平臺上有所不同。 (另外,我使用的大多數C編譯器都會使用mangle的名字,只是比C++簡單得多。) – 2012-04-12 17:00:31

15

該標準實際上並不要求名稱修改。對於這個問題,標準不要求IEEE浮點數或二進制補碼整數或任何數量的其他東西。

直到有一個普遍的ABI它可以依靠,GCC actually went out of its way to use a different name mangling scheme比競爭對手:

G ++不做名稱以同樣的方式與其他C++編譯器重整。這意味着使用一個編譯器編譯的目標文件不能與另一個編譯器一起使用。

此效果是故意的,以保護您免受更微妙的問題。編譯器對C++實現的許多內部細節有所不同,包括:如何佈置類實例,如何實現多重繼承以及如何處理虛函數調用。如果名稱編碼是相同的,那麼您的程序將與其他編譯器提供的庫鏈接,但程序運行時會崩潰。然後在鏈接時檢測不兼容的庫,而不是在運行時檢測。

名稱修改比許多程序員意識到的還要複雜。例如,標準將如何指定acceptable calling conventions for all platforms that C++ could run on?即使RISC系統通常將它們的參數傳遞到寄存器而不是棧中,RISC系統是否需要支持x86 stdcall