2012-12-21 42 views
3

考慮我的小例子C庫:獲得GCC鏈接器警告多個函數定義

#include <external_library.h> 

void some_function(void) 
{ 
    external_library_call(); 
    // Do other stuff... 
} 

它計劃使some_function()調用公開。但是,該庫不起作用,因爲它需要的外部庫也恰好使用了一個名爲some_function()的函數,該函數恰好具有相同的原型。儘管如此,GCC的鏈接器並不在乎有多少some_function符號來源。它從表面上隨機挑選一個,外部庫可能會或可能不會使用我的some_function()而不是它自己的。瘋了吧。不是圖書館不工作的事實。這個庫肯定不應該工作。事實上,符號'some_function'有兩個來源,但鏈接程序對此不做任何事情。而且你知道,這並不會讓我感到困擾,因爲我已經習慣了GCC和C,一般在病態上都是魯莽的。但是,有一種方法可以讓鏈接器在相同符號有兩個來源時提醒我。我已經嘗試過--Wall -Wextra -Wshadow,但是不會產生任何警告。

請注意,-fvisibility = hidden在這裏沒有幫助,因爲這兩個庫都希望導出some_function()。我知道你可以對我進行函數調用時沒有一個唯一的前綴而感到羞恥。你是對的。這是一個錯誤。我不在乎。這個錯誤可以被鏈接器捕獲,所以應該被捕獲。沒有理由爲什麼鏈接器不應該捕獲這個錯誤。此外,您使用的庫可能會導出一些奇怪的意外符號,並且您不一定能控制其他人的庫導出內容。只有在程序員停止並着火之前,前綴和前綴才能變得非常獨特。

回答

1

地址:

-fvisibility=hidden

到您的構建標誌。注意一些警告,但是;一些標題可能不會期待這一點。在這種情況下,你需要包括之前使用編譯:

#pragma GCC visibility push(hidden) 
#include <problematic_header> 
#pragma GCC visibility pop 

達到這一目的有其他一些其他的好處不僅僅是避免符號衝突。請參閱:

http://gcc.gnu.org/wiki/Visibility

如果你有興趣。

+0

如果我正確讀取這個,我還必須在main()前面添加__attribute __((visibility(「default」)))來導出它。正確? – enigmaticPhysicist

+0

@enigmaticPhysicist我不這麼認爲。 main()似乎被GCC專門處理並始終導出。 –

+0

雖然這是非常有用的,我一定會使用它,它不能解決原來的問題。鏈接器/知道/有相同符號的兩個單獨的實例。爲什麼它沒有停下來併發生錯誤?爲什麼選擇一個而不是另一個?什麼標準?如果我需要導出一個符號,並且我想確保它不會與我正在使用的任何其他符號相沖突,那該怎麼辦?我仍然稱這個問題沒有解決,直到我可以讓鏈接器在這種情況下停止出現錯誤。 – enigmaticPhysicist

0

諸如-Wall -Wextra -Wshadow之類的選項是影響源代碼分析的編譯器標誌;顯然,你在鏈接器選項之後。

但是,由於shutdown()位於爲應用程序保留的命名空間中(並且您甚至不顯示您已經包含聲明系統shutdown()的標頭),所以編譯器或鏈接程序沒有多大用處做。您作爲應用程序員有權創建一個名爲shutdown()的函數並調用它。你可以看看像LSB(Linux標準庫)合規性套件這樣的東西來檢查你是不是定義實現定義的函數。

我曾經追蹤過的一個較難的錯誤涉及到函數_bind()在我們的代碼中碰巧與具有不同接口的系統函數_bind()相同。當我們的功能被系統庫的某些部分調用時,所有的地獄都會崩潰。這部分是我們使用保留給系統的名稱的一部分(不要用_啓動變量或函數名稱),但不幸的是,只有一個平臺有名稱衝突。我們的_bind()系統前綴解決了這個問題。

您可以查看C和POSIX標準中的保留名稱列表。但是,您會發現_t後綴是保留的,但帶有後綴的類型名稱也廣泛用於用戶定義的類型(ab)。您還必須知道任何給定類型的定義是'來自系統頭'(大概是OK),還是來自用戶定義的頭(可能不是OK),還是'提供缺少系統功能的用戶定義頭' (邊緣)。它變得非常棘手。

+0

關於_bind()錯誤:我不認爲這是你的錯。在某些時候,鏈接器必須意識到_bind()有兩個定義。鏈接器沒有辦法知道這一點。除非有關於鏈接器操作的一些細節,我不熟悉...... – enigmaticPhysicist

+0

實際上,編譯時鏈接器是否從未檢查過鏈接的共享對象的符號表?這是我能想到的唯一解釋。即使如此,它仍然有點魯莽。 – enigmaticPhysicist