Kahler
Kahler

Reputation: 1150

Where is the function that a decayed lambda points to stored? How is it freed?

I've recently learned that I can do this:

auto a = +[]{return true;};
a = +[]{return false;};

And understood that the capture-free lambda decays to a function pointer, as confirmed by GCC:

bool (*)()

But where is the actual function object stored? How is it freed? Why can I store a pointer to a temporary lambda? I understand that corner-case of the the language where constant references extend the lifetime of an object, so I expected the lambda to decay to something of that kind, not a raw pointer.

Upvotes: 1

Views: 439

Answers (1)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275760

The lambda is not a pointer, but can be converted into a pointer-to-function.

Functions are not "stored" like values in C++. In practice, they exist in a code segment of the executable, and are loaded into write-protected execute-bit-set pages by the executable/dll loader.

The stateless lambda's code is no different. The conversion just returns a pointer to a function with the same effect as the body of the lambda, no more, no less.

Remember this only works with stateless lambdas. There is no non-static data to be stored.

Now, the + thing is a bit of a trick, in that when you apply unary operator+ to an object, conversion is attempted, and one uniqie type (conversion of the function object to function pointer) is found.

I guess concrete code may help.

struct fake_lambda {
  static void action(){ std::cout<<"hello?\n"; }
  void operator()()const{action();}
  using ptr=void(*)();
  operator ptr()const{return &fake_lambda::action;}
};

Now auto f=+fake_lambda{}; is a pointer to a function that prints "hello?\n".

This is basically the same as auto f=+[](){std::cout<<"hello\n";};, but more verbose.

Upvotes: 5

Related Questions