为什么在从c ++代码发出LLVM IR时,如果未调用该函数,则LLVM-IR中不显示模板函数,
与其他类型的函数(int,float ...)不同,它将出现在llvm ir中
示例:以下函数func1
未在llvm ir
template <class tmp>
tmp func1 () {
// ...
}
但是这个函数func2
总是显示在llvm ir
int func2 () {
// ...
}
答案 0 :(得分:5)
这是因为您的模板不是函数:它们是函数模板。在用参数实例化之前,它们不是发现。例如,请使用以下代码:
template<typename T>
T foo() { /* ... */ }
那也不会输出任何代码。
但另一方面,这是:
template<typename T>
T foo() { /* ... */ }
int test() {
return foo<int>();
}
将输出test
和foo<int>
的代码。
您也可以手动实例化这样的模板:
template int foo<int>();
答案 1 :(得分:4)
这与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 ++程序中都有很多类型,并且可以添加许多类型,并且几乎每个都以不同的方式添加,因此在知道此类型之前,它无法为该函数创建代码。如果它试图为所有可能的类型T
执行此操作,您将获得可能实现的组合爆炸,几乎所有类型都从未使用过。如果有任何好处,你的编译时间和二进制大小将是巨大的。
class templates使事情变得更加复杂。如果未调用类模板的实例化实际上不需要实例化所有函数。回到我们的例子,如果我们写了:
template <typename T>
class Adder {
T add(T left, T right) {
return left + right;
}
};
Adder<int> a;
这个仍然不会实例化Adder<int>::add
,即使编译器已经知道add<int>
可能有趣的所有信息,因为你实际上 调用或以其他方式实例化它。