I have some tortuous code in a template that uses @R. Martinho Fernandes's trick to loop unroll some packed parameters in a variadic template and invoke the same code on each argument in the argument list.
However, it seems as though the lambdas are not being initialized properly and they are instead sharing variables across functor(?) instances, which seems wrong.
Given this code:
#include <iostream>
#include <functional>
template<typename... Args>
void foo(Args ... args) {
int * bar = new int();
*bar = 42;
using expand_type = int[];
expand_type{(
args([bar]() {
std::cerr<<std::hex;
std::cerr<<"&bar="<<(void*)&bar<<std::endl;
std::cerr<<" bar="<<(void*)bar<<std::endl;
std::cerr<<" bar="<<*bar<<std::endl<<std::endl;
}),
0) ...
};
};
int main() {
std::function<void(std::function<void()>)> clbk_func_invoker = [](std::function<void()> f) { f(); };
foo(clbk_func_invoker, clbk_func_invoker);
return 0;
}
I get the following output:
&bar=0x7ffd22a2b5b0
bar=0x971c20
bar=2a
&bar=0x7ffd22a2b5b0
bar=0
Segmentation fault (core dumped)
So, what I believe I'm seeing is that the two functor instances share the same address for captured variable bar
, and after the invocation of the first functor, bar
is being set to nullptr
, and then the second functor seg'-faults when it tries to dereference the same bar
variable ( in the exact same address ).
FYI, I realize that I can work around this issue by moving the [bar](){...
functor into a variable std::function
variable and then capturing that variable. However, I would like to understand why the second functor instance is using the exact same bar
address and why it is getting a nullptr
value.
I ran this with GNU's g++ against their trunk version retrieved and compiled yesterday.