人们通常说,只有在编译时知道如何调用函数或对此有所了解的情况下,才能内联函数。 (请纠正/澄清我是否错了)

所以说如果我有这样的功能

void Calling()
{
if (m_InputState == State::Fast) //m_inputstate is a class member and is set by user
{
CallFastFunction();
}
else if (m_InputState == State::Slow)
{
CallSlowFunction();
}
}


由于m_inputstate由最终用户设置,我们可以说这个变量在编译时是未知的,因此call()不能内联吗?

最佳答案

编译器可以(几乎可以肯定)内联您的Calling函数。根据CallFastFunctionCallSlowFunction的来源的可用性,它们也可以内联。

如果编译器可以确定m_InputState的值,它将删除if-但仅在确定该值是一个值的情况下。

例如,thing.m_InputState = State::Slow; thing.Calling();将仅在“慢速”调用中编译,而没有任何条件代码,而std::cin >> thing.m_InputState; thing.Calling();当然不会。

如果通过基于配置文件的优化,编译器知道选择每种情况的频率,则它也可以按代码顺序选择哪个路径以“下一个”结尾,从而最有可能排在最前面(并且可能向处理器提供前缀或其他指示“您很可能会这样”。

但是内联本身的发生基于:


代码本身可用。
函数调用的大小和数量。
我们不知道的任意编译器决定(除非我们对编译器的源代码非常熟悉)。


现代的编译器还支持“链接时间优化”,其中生成的目标文件只是“半完成”,因此链接器实际上会生成最终代码,并且可以四处移动和内联代码,就像旧代码一样。老式的编译器,在组成可执行文件的所有代码上(所有代码都使用链接时优化),允许内联那些没有相同源文件或头文件中没有代码的代码。

10-08 08:24
查看更多