爲什麼模板函數在LLVM-IR中不顯示,如果函數未被調用,當從C++代碼發出LLVM IR時, 不像其他類型的函數(int,float ...)會出現在llvm中IR 例如:下面的函數func1
犯規秀LLVM IR爲什麼模板函數不能顯示在LLVM-IR中?
template <class tmp>
tmp func1() {
// ...
}
但這個功能func2
始終顯示在LLVM IR
int func2() {
// ...
}
爲什麼模板函數在LLVM-IR中不顯示,如果函數未被調用,當從C++代碼發出LLVM IR時, 不像其他類型的函數(int,float ...)會出現在llvm中IR 例如:下面的函數func1
犯規秀LLVM IR爲什麼模板函數不能顯示在LLVM-IR中?
template <class tmp>
tmp func1() {
// ...
}
但這個功能func2
始終顯示在LLVM IR
int func2() {
// ...
}
這是導致你的模板不是功能:它們是功能模板。在用參數實例化之前,它們不是調查結果。例如,拿這個代碼:
template<typename T>
T foo() { /* ... */ }
那也不會輸出任何代碼。
但這在另一方面:
template<typename T>
T foo() { /* ... */ }
int test() {
return foo<int>();
}
將輸出兩個test
和foo<int>
代碼。
您也可以手動實例化這樣的一個模板:
template int foo<int>();
這與how C++ templates work做。由於編譯器在調用函數(或者更確切地說,當您實例化它)之前不知道tmp
是什麼,它不知道如何爲它編寫代碼。例如,考慮這個模板:
template <typename T>
T add(T left, T right) {
return left + right;
}
如果T
是一個整數,那麼函數體是一個整數加。如果T
是雙精度浮點數,則它是一個浮點數。如果T
的std::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>
是潛在的有趣,因爲你不實際調用或以其他方式實例化它。
這不是*模板函數*。這是一個*函數模板*。這不是一種功能,而是未來功能的藍圖。這是完全無關緊要的。'func'將是*模板函數*,即所有模板參數已知的*函數模板*。這*實例化模板,使其「實現」。 –
AnT