2017-02-03 116 views
1

爲什麼模板函數在LLVM-IR中不顯示,如果函數未被調用,當從C++代碼發出LLVM IR時, 不像其他類型的函數(int,float ...)會出現在llvm中IR 例如:下面的函數func1犯規秀LLVM IR爲什麼模板函數不能顯示在LLVM-IR中?

template <class tmp> 
tmp func1() { 
    // ... 
} 

但這個功能func2始終顯示在LLVM IR

int func2() { 
    // ... 
} 
+1

這不是*模板函數*。這是一個*函數模板*。這不是一種功能,而是未來功能的藍圖。這是完全無關緊要的。'func '將是*模板函數*,即所有模板參數已知的*函數模板*。這*實例化模板,使其「實現」。 – AnT

回答

5

這是導致你的模板不是功能:它們是功能模板。在用參數實例化之前,它們不是調查結果。例如,拿這個代碼:

template<typename T> 
T foo() { /* ... */ } 

那也不會輸出任何代碼。

但這在另一方面:

template<typename T> 
T foo() { /* ... */ } 

int test() { 
    return foo<int>(); 
} 

將輸出兩個testfoo<int>代碼。

您也可以手動實例化這樣的一個模板:

template int foo<int>(); 
4

這與how C++ templates work做。由於編譯器在調用函數(或者更確切地說,當您實例化它)之前不知道tmp是什麼,它不知道如何爲它編寫代碼。例如,考慮這個模板:

template <typename T> 
T add(T left, T right) { 
    return left + right; 
} 

如果T是一個整數,那麼函數體是一個整數加。如果T是雙精度浮點數,則它是一個浮點數。如果Tstd::string,這是一個函數調用std::string::operator+。由於在任何C++程序中都有很多類型,並且可以添加其中的很多類型,並且幾乎每種類型都以不同的方式添加,所以在知道此類型之前,不能爲該函數創建代碼。如果它試圖對所有可能的類型執行此操作,那麼您可能會遇到可能實現的組合式爆炸,幾乎所有這些操作都不會被使用。你的編譯時間和二進制文件的大小將會很大,如果有什麼好處的話,很少。


事情變得稍微複雜一點,class templates。類模板的實例化實際上並不需要實例化所有函數,如果它們沒有被調用。回到我們的例子,如果我們不是這樣寫道:

template <typename T> 
class Adder { 
    T add(T left, T right) { 
     return left + right; 
    } 
}; 

Adder<int> a; 

仍然不會實例Adder<int>::add即使編譯器擁有所有的信息,知道add<int>是潛在的有趣,因爲你不實際調用或以其他方式實例化它。

相關問題