为什么模板函数不能显示在LLVM-IR中?
为什么模板函数在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