C++ Lambda 的内存布局
Memory layout of a C++ Lambda
为了更好地理解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 的捕获,因此甚至可以省略......
相关文章:
- 将布局映射到内存地址
- C++继承的虚拟类的内存布局
- 检查nullptr是否100%保护内存布局不受segfault影响
- C++ Python 的扩展 - 安全内存访问和内存布局
- 类似元组的类模板的反向内存布局
- 在C++标准中记录对象的内存布局的哪个位置?
- C++ Lambda 的内存布局
- 打包类的内存布局 + 继承
- 假设传递给 OpenGL 的结构数组的内存布局存在潜在错误
- COM 互操作结构定义与内存布局不匹配
- C++非虚拟类成员变量内存布局?
- 结构中的内存布局差异
- 2D 区域的内存布局
- 如果"原子"<T>是无锁的并且与"T"的大小相同,内存布局是否相同?
- 是C 单继承的内存布局与此C代码相同
- 直观的内存布局,可实现快速SIMD/面向数据的设计
- 使用GDB并检查Data的内存布局
- 对齐方式究竟如何影响内存布局和新放置的巴哈维?
- 数组向量的内存布局是什么
- 为什么C 标准专门为具有不同访问说明符的类数据成员的内存布局提供了余地