为什么模板函数不会出现在LLVM-IR中?

时间:2017-02-03 18:23:37

标签: c++ llvm llvm-clang llvm-ir

为什么在从c ++代码发出LLVM IR时,如果未调用该函数,则LLVM-IR中不显示模板函数, 与其他类型的函数(int,float ...)不同,它将出现在llvm ir中 示例:以下函数func1未在llvm ir

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

但是这个函数func2总是显示在llvm ir

int func2 () {
    // ...
}

2 个答案:

答案 0 :(得分:5)

这是因为您的模板不是函数:它们是函数模板。在用参数实例化之前,它们不是发现。例如,请使用以下代码:

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

那也不会输出任何代码。

但另一方面,这是:

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

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

将输出testfoo<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是一个双精度数,则它是一个浮点数加法。如果Tstd::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>可能有趣的所有信息,因为你实际上 调用或以其他方式实例化它。