人们通常说,只有在编译时知道如何调用函数或对此有所了解的情况下,才能内联函数。 (请纠正/澄清我是否错了)
所以说如果我有这样的功能
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
函数。根据CallFastFunction
和CallSlowFunction
的来源的可用性,它们也可以内联。
如果编译器可以确定m_InputState
的值,它将删除if
-但仅在确定该值是一个值的情况下。
例如,thing.m_InputState = State::Slow; thing.Calling();
将仅在“慢速”调用中编译,而没有任何条件代码,而std::cin >> thing.m_InputState; thing.Calling();
当然不会。
如果通过基于配置文件的优化,编译器知道选择每种情况的频率,则它也可以按代码顺序选择哪个路径以“下一个”结尾,从而最有可能排在最前面(并且可能向处理器提供前缀或其他指示“您很可能会这样”。
但是内联本身的发生基于:
代码本身可用。
函数调用的大小和数量。
我们不知道的任意编译器决定(除非我们对编译器的源代码非常熟悉)。
现代的编译器还支持“链接时间优化”,其中生成的目标文件只是“半完成”,因此链接器实际上会生成最终代码,并且可以四处移动和内联代码,就像旧代码一样。老式的编译器,在组成可执行文件的所有代码上(所有代码都使用链接时优化),允许内联那些没有相同源文件或头文件中没有代码的代码。