【问题标题】:Do C++ compilers make an independent decision about inlining a lambda function and its caller?C++ 编译器是否对内联 lambda 函数及其调用者做出独立决定?
【发布时间】:2013-07-16 20:00:45
【问题描述】:

考虑以下使用 lambda 的函数。

void printAll( const std::vector< std::string >& strings )
{
    auto fn = [] ( const std::string& s )
    {
        std::cout << s << std::endl;
    };

    std::for_each( strings.begin(), strings.end(), fn );
}

现在很清楚,如果完全启用内联,编译器将决定是否内联printAll() 函数。 (我将放弃关于它如何做出这个决定的脱轨讨论,inline 关键字的存在与否是否与它有关,“整个程序”优化系统等等。)

我的问题是编译器如何处理是否内联fn 的问题。是吗:

  • 内联fn当且仅当它内联printAll()?
  • 总是内联fn?
  • 从不内联fn
  • fn 做出独立决定,本质上将其视为一个完全独立的功能?
  • 首先使用通常的启发式方法确定fn,然后根据fn 是否内联来决定内联printAll()

...或遵循其他一些政策?

这个答案是由 C++ 规范规定的,还是编译器实现者可以随意回答?

P。 S. 我知道std::for_each() 将其函数参数作为模板参数,并且模板为内联问题带来了自身的复杂性。除非我弄错了,否则这个细节与问题无关,它与如何做出关于 lambda 和调用它们的函数的内联决策有关。请不要让它不必要地分散您的注意力。

【问题讨论】:

  • lambdas 和模板参数 functionoids 只是具有关联状态的函数,与常规函数+全局变量没有什么不同。由于它们与任何其他函数基本相同,因此它们应该遵循与任何其他函数相同的内联策略。

标签: c++ function c++11 lambda inline


【解决方案1】:

printAll 内内联对fn 的调用的决定独立于内联printAll 的决定。特别是,fn 在所有编译器中被内联的可能性非常高,std::for_each 也是如此,但是因为printAll 包含一个循环(for_each 中的那个),内联的可能性在某些情况下会下降编译器(内联的一些启发式方法包括代码的复杂性和循环的存在)。

从选项列表中,最佳匹配是:

首先使用通常的启发式决定 fn,然后根据 fn 是否内联来决定内联 printAll()?

尽管for_each 的内联缺少一个中间步骤,这对于启发式算法本身很重要。

请注意,标准中并没有保证编译器会做什么,所以如果你真的很在意,请查看生成的汇编器

【讨论】:

    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多