語法
GNU編譯器集合和Solaris Studio C編譯器共享相同的語法,用於將符號注釋為弱,即特殊的#pragma,#pragma weak,以及函式和變數屬性__attribute __((weak))。
編譯
屬性
支持平台
nm命令標識目標檔案,庫和執行檔中的弱符號。 在Linux上,如果弱默認定義可用,則弱函式符號標記為“W”,如果不可用,則標記為“w”。 弱定義的變數符號標有“V”和“v”。 在Solaris上,“nm”為弱符號列印“WEAK”而不是“GLOB”。
實例
靜態實例
main.c:
power_slow.h:
power_slow.c:
power.c:
Build commands:
輸出
刪除weak屬性並重新執行build命令時,最後一個失敗並顯示以下錯誤訊息(在Linux上):
倒數第二個仍然成功,而./slow具有相同的輸出。
共享實例
從前面的例子中取main.c並添加:
用以下內容替換power_slow.c:
構建命令:
輸出
刪除weak屬性並重新執行構建命令不會產生構建錯誤,並導致main和main2的輸出(在Linux上)相同。 main3的構建命令導致以下警告和錯誤訊息(在Linux上):
警告由編譯器發出,因為它可以靜態地確定if(user_hook)表達式user_hook總是評估為true,因為它包含ELF跳轉表條目。 錯誤訊息由連結器發出。 main4的構建包含相同的警告但沒有連結錯誤。
套用
弱符號可以用作提供功能的默認實現的機制,其可以在連結時由更專業(例如,最佳化的)替換。 然後將默認實現聲明為弱,並且在某些目標上,具有強聲明符號的目標檔案將添加到連結器命令行。
如果庫將符號定義為弱符號,則連結該庫的程式可以自由地提供強大的符號,例如,用於自定義目的。
弱符號的另一個用例是維護二進制向後兼容性。
相關方法
C預處理器(CPP)條件結構也可用於在符號的不同版本之間切換。 與弱符號的區別在於弱符號由連結器解釋。 CPP在C編譯器之前編譯每個轉換單元期間運行。
構建過程(例如make)可以以條件方式實現,使得僅創建符號的不同版本或者根據目標使用和連結不同(專用)庫。