简体   繁体   English

C++ Lambda 的内存布局

[英]Memory layout of a C++ Lambda

In trying to better understand the implementation of C++ lambdas, I fooled the compiler into treating a lambda as an object, and it seems that they are laid-out the same way in memory.为了更好地理解 C++ lambda 的实现,我欺骗了编译器将 lambda 视为一个对象,而且它们似乎在内存中的布局方式相同。

Note : This is just for clarification, I'm not advocating writing these kinds of hacks in production注意:这只是为了澄清,我不提倡在生产中编写这些类型的 hack

Is this guaranteed by the language spec, or a compiler implementation detail?这是由语言规范或编译器实现细节保证的吗?

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

}

The standard does not require lambda closures to have a particular layout.该标准不要求 lambda 闭包具有特定的布局。 See [expr.prim.lambda.closure] :[expr.prim.lambda.closure]

The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type, whose properties are described below. lambda 表达式的类型(也是闭包对象的类型)是唯一的、未命名的非联合类类型,称为闭包类型,其属性如下所述。

... ...

The closure type is not an aggregate type.闭包类型不是聚合类型。 An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:一个实现可以定义与下面描述的不同的闭包类型,前提是这不会改变程序的可观察行为,除了改变:

  • the size and/or alignment of the closure type,闭合类型的大小和/或对齐方式,
  • whether the closure type is trivially copyable, or闭包类型是否可简单复制,或
  • whether the closure type is a standard-layout class.闭包类型是否为标准布局类。

An implementation shall not add members of rvalue reference type to the closure type.实现不应将右值引用类型的成员添加到闭包类型。


However, to conform to the platform ABI and to have object files interoperable, the compilers probably have to layout and name mangle lambda objects in absolutely the same way.但是,为了符合平台 ABI 并使对象文件可互操作,编译器可能必须以完全相同的方式布局和命名 mangle lambda 对象。

This is entirely implementation-defined.这完全是实现定义的。
However, since lambdas are just instances of classes, it makes sense that they'd be generated by the compiler to look like any other class.但是,由于 lambda 只是类的实例,因此编译器生成它们看起来像任何其他类是有道理的。

Implementation specific.具体实现。

Moreover, in your case, capture of lambda are not used, so might even be elided...此外,在您的情况下,未使用 lambda 的捕获,因此甚至可能会被省略...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM