2015-11-03 52 views
2

試想一下,下面的函數在靜態庫中存在(*。A,* .LIB):死代碼消除在switch語句

int func_foo(int i) { 
    switch (i) { 
    case 1: 
     return foo_bar(); 
    case 2: 
     return foo_baz(); 
    case 3: 
     return foo_bat(); 
    default: 
     return -1; 
    } 
} 

如果這個庫調用此功能的用戶,只有通過在1 ,會(或可以)編譯器刪除對23的呼叫嗎?

編譯器是否也會刪除foo_baz()foo_bat()函數(如果它們沒有在其他函數中被引用)(也就是死代碼消除)?

+0

「這個圖書館的用戶」如何攝取圖書館?參考源代碼或一些現成的二進制文件? –

+0

假設它是一個編譯的靜態庫(例如* .a或等價的)。 – MarkP

回答

2

如果Whole Program Optimization已啓用且func_foo未標記爲從輸出共享對象庫或DLL中導出,像MSVC這樣的體面編譯器可以並將刪除此類死代碼。因此,代碼看起來像這樣(當然忽略內聯函數):

int func_foo(int i) { 
    return foo_bar(); 
} 

否則,如果WPO未啓用和func_foo具有外部鏈接(默認),編譯器不能去除死代碼。最後,如果WPO未啓用且func_foo具有靜態鏈接,則編譯器可以刪除死者。在最後一種情況下,MSVC沒有執行優化。其他編譯器可能會執行它。

編譯器是否也刪除foo_baz()和foo_bat()函數,如果 它們沒有在任何其他函數中引用?

這又取決於WPO是打開還是關閉,如果它關閉,則取決於函數的鏈接。在所有情況下,這些功能都不能導出。另外,你必須明確地告訴編譯器使用編譯器開關去除未引用的函數。例如,在MSVC中,您必須使用/Gy編譯器開關和/OPT:NOREF鏈接器開關。