Compiling

靜態連結到 .a 文件時,C 編譯器會丟棄未使用的函式嗎?

  • September 3, 2022

假設我有一個main.c靜態連結到libmine.a. 靜態連結到庫會導致庫函式在編譯時嵌入到主執行檔中。

如果libmine.a要具有未被使用的功能,main.c編譯器(例如GCC)會丟棄這些功能嗎?

這個問題的靈感來自使用靜態庫使執行檔更大的“常見消息”,所以我很好奇編譯器是否至少從存檔文件中刪除了未使用的程式碼。

預設情況下,連結器將目標文件作為一個整體來處理。在您的範例中,執行檔最終將包含來自main.c( main.o) 的程式碼,以及提供 (傳遞性) 使用的所有功能所需的任何目標文件libmine.a(這是目標文件的存檔main.c)。

所以連結器不一定包括所有libmine.a,但它可以使用的粒度不是函式(預設情況下),它是目標文件(嚴格來說,節)。

但是,如果靜態庫包含額外的資訊以允許連結器單獨處理函式,則現代編譯器和連結器可以做得更好。使用 GCC,在啟用選項的情況下建構.o文件-ffunction-sections -fdata-sections,並將最終程序與--gc-sections選項鍊接。這確實會產生影響,尤其是通過阻止某些類別的優化;有關詳細資訊,請參閱丟棄 GCC中未使用的函式。

您可以與現代編譯器和連結器一起使用的另一個選項是連結時優化。啟用此功能-flto。啟用優化時(例如 -O2編譯目標文件時),連結器將不會在生成的二進製文件中包含未使用的函式。即使沒有-ffunction-sections -fdata-sections.

引用自:https://unix.stackexchange.com/questions/715899