Compiling
靜態連結到 .a 文件時,C 編譯器會丟棄未使用的函式嗎?
假設我有一個
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
.