C++ Lambda 的内存布局

Memory layout of a C++ Lambda

本文关键字:布局 内存 Lambda C++      更新时间:2023-10-16

为了更好地理解C++lambda的实现,我欺骗编译器将lambda视为对象,并且它们似乎在内存中的布局方式相同。

注意:这只是为了澄清,我不主张在生产中编写此类黑客

这是由语言规范还是编译器实现细节保证的?

struct F
{
int a;  int b;  int c;
void printLambdaMembers()
{
cout << this << endl; // presumably the lambda 'this'
cout << a << endl; // prints 5   
cout << b << endl;
cout << c << endl;
}
};
void demo()
{
int a = 5;
int b = 6;
int c = 7;
auto lambda = [a,b,c]() { cout << "In lambda!n";  };
// hard cast the object member function pointer to the lambda function 
void(decltype(lambda)::*pf)() const = (void(decltype(lambda)::*)() const) (&F::printLambdaMembers);
// run the member function on the lambda pointer
(lambda.*pf)();  // we get 5,6,7
}

该标准不要求 lambda 闭包具有特定的布局。请参阅[expr.prim.lambda.closure]

lambda 表达式的类型(也是闭包对象的类型(是一种唯一的、未命名的非联合类类型,称为闭包类型,其属性如下所述。

闭包类型不是聚合类型。实现可以定义与下面描述的不同闭包类型,前提是这不会改变程序的可观察行为,除了通过更改:

  • 闭合类型的尺寸和/或对齐方式,
  • 闭包类型是否易于复制,或者
  • 闭包类型是否为标准布局类。

实现不得将右值引用类型的成员添加到闭包类型。


但是,为了符合平台 ABI 并使对象文件可互操作,编译器可能必须以完全相同的方式布局和命名 lambda 对象。

这完全是实现定义的。
但是,由于 lambda 只是类的实例,因此编译器生成它们看起来像任何其他类是有道理的。

特定于实现。

此外,在您的情况下,不使用 lambda 的捕获,因此甚至可以省略......