【问题标题】:Why template functions do not show up in the LLVM-IR?为什么模板函数没有出现在 LLVM-IR 中?
【发布时间】:2017-02-03 18:23:37
【问题描述】:

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

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

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

int func2 () {
    // ...
}

【问题讨论】:

  • 这不是一个模板函数。这是一个函数模板。它不是功能,而是未来功能的蓝图。这是完全无关紧要的。 func&lt;int&gt; 将是一个模板函数,即一个所有模板参数已知的函数模板。这实例化模板,使其“具体化”。

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


【解决方案1】:

这是因为您的模板不是函数:它们是函数模板。在使用参数实例化之前,它们不会被编译。比如下面这段代码:

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

那也不会输出任何代码。

但另一方面:

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

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

将输出testfoo&lt;int&gt; 的代码。

您也可以像这样手动实例化模板:

template int foo<int>();

【讨论】:

    【解决方案2】:

    这与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&lt;int&gt;::add,即使编译器知道add&lt;int&gt;可能很有趣,因为你没有实际上调用或以其他方式实例化它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      相关资源
      最近更新 更多