我最近需要一个通过引用捕获多个局部变量的lambda,所以我制作了一个测试片段来研究它的效率,并-O3使用clang 3.6 编译它:
void do_something_with(void*);
void test()
{
int a = 0, b = 0, c = 0;
auto func = [&] () {
a++;
b++;
c++;
};
do_something_with((void*)&func);
}
Run Code Online (Sandbox Code Playgroud)
movl $0x0,0x24(%rsp)
movl $0x0,0x20(%rsp)
movl $0x0,0x1c(%rsp)
lea 0x24(%rsp),%rax
mov %rax,(%rsp)
lea 0x20(%rsp),%rax
mov %rax,0x8(%rsp)
lea 0x1c(%rsp),%rax
mov %rax,0x10(%rsp)
lea (%rsp),%rdi
callq ...
Run Code Online (Sandbox Code Playgroud)
显然,lambda只需要一个变量的地址,所有其他变量都可以通过相对寻址来获得.
相反,编译器在堆栈上创建了一个包含指向每个局部变量的指针的结构,然后将结构的地址传递给lambda.这和我写的一样:
int a = 0, b = 0, c = 0;
struct X
{
int *pa, *pb, *pc;
};
X x = {&a, …Run Code Online (Sandbox Code Playgroud)