Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory layout of a C++ Lambda

Tags:

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.

Note: This is just for clarification, I'm not advocating writing these kinds of hacks in production

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

}
like image 238
Gonen I Avatar asked Jun 26 '26 12:06

Gonen I


2 Answers

The standard does not require lambda closures to have a particular layout. See [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.

...

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.

like image 73
Maxim Egorushkin Avatar answered Jun 28 '26 01:06

Maxim Egorushkin


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.

like image 32
Quentin Avatar answered Jun 28 '26 02:06

Quentin