内联lambda是否遭受与函数指针间接寻址相同的延迟

Do inline lambdas suffer the same latency of function pointer indirect addressing

本文关键字:间接寻址 延迟 指针 函数 是否 lambda 内联      更新时间:2023-10-16
// approach 1
template <typename T>
void f1(T t, int a, int b) {
t(a, b);
}
// approach 2
void f2(void(*g)(int, int), int a, int b) 
{
g(a, b); 
}
void g (int a, int b) 
{
// do something
}
int main() 
{
f1([](int a, int b)
{ 
//do something 
}, 1, 2);
f2(&g, 1, 2);
}

我的问题是,f1f2在获得要执行的函数的地址时是否会经历相同的间接寻址延迟(假设lambda是作为函数对象实现的)?

如果lambda不是内联的呢?

注意:我将函数f1声明为模板,将参数lambda类型的推导留给编译器(例如,不要强制执行std函数,但不确定它是否有区别)。

从概念上讲,编译器应该能够内联lambda主体。使用lambda是编译时的事情,这意味着编译器确切地知道要调用什么函数,因此它应该能够内联代码。对于函数指针,传递的函数直到运行时才真正知道,因此编译器有更多的工作要做,看看是否可以内联它。通常,代码不是内联的,通过指针可以间接访问。

f1和f2在获取要执行的函数的地址时是否经历了相同的间接寻址延迟(假设lambda是作为函数对象实现的)?

该标准没有指定任何关于延迟的保证。但是lambda调用没有任何理由比对常规内联函数的调用有更多的延迟。编译器可以在编译时确定生成函数的地址,并且不需要间接寻址。

调用函数指针可能需要间接操作的开销,除非函数已经内联扩展,在这种情况下,指针的值可能在编译时在扩展的上下文中是已知的。

如果lambda不是内联的呢?

不能声明lambda,也不能在另一个编译单元中定义它。所有Lambda都是内联的。

注意:我将函数f1声明为模板,将参数lambda类型的推导留给编译器(例如,不是强制执行std函数,但不确定它是否有区别)。

std::function的开销至少与函数指针的开销一样多。