On 11 Sep 2021 21:19, Bonita Montero wrote:
> Something I wondered about is whether it is possible to get a C function
> pointer from a local static lambda _with_ captures like this:
>
> #include <iostream>
>
> int main()
> {
> int i;
> static
> auto lambda = [&i]()
> {
> ++i;
> };
> void (*pLambda)() = lambda;
> }
This particular example — the lines of code up to the hypothetical
declaration of `pLambda` — is flawed because if you put this code in any
function other than `main` it will then use a dangling reference on
second call of that function.
---
> In theory this should be possible since the lambda doesn't need
> its own context-pointer (pseudo-"this") since the capture-context
> is global storage.
If you make `i` static then you have something that a smart enough
compiler can rewrite to a capture-less lambda. Don't know if they do
though. And conversion to C function pointer would need to be a language
extension.
---
> This seems something the designers of C++ didn't
> consider, although it is of little use.
You can get a freestanding function that references any C++ object
simply by storing a reference or pointer to (a copy of) that object
indirectly or directly in a static variable that the function uses.
For example, the type of the static variable can be `std::function<void()>`.
And that scheme can be elaborated to provide a function that you can use
like `as_c_callback( [&]{ ++i; } )`. To make that safe against multiple
overlapping uses of `as_c_callback` let the static variable be a
collection, e.g. with the return type of `as_c_callback` as a RAII
object with implicit conversion to C function pointer. To make it thread
safe use thread local storage. Uhm, not sure how to make it fool proof.
But if such elaborations are adopted it can probably be a good idea to
separate the elaborations from the basic simple scheme.
- Alf