I'm trying to build a lambda that wraps some input functions with some pre/post actions.
What puzzles me is that the crash depends on the compiler: the code works perfectly fine with Xcode 6 clang
(clang-3.6
based), but crashes on linux using clang++-3.6
and g++4.8.4
.
I've made a small program that reproduces the behaviour:
#include <iostream>
#include <string>
#include <functional>
using namespace std;
typedef function<void(void)> NestedFn;
int main()
{
// Create a cfunction
auto lambdaFactory = [&](string title, NestedFn nestedFunc)
{
// title is copied to the new lambda
return [&, title]() {
cerr << "------------ START -----------" << endl;
cerr << "Inside: " << title << endl;
nestedFunc();
cerr << "------------- END ------------" << endl;
};
}
auto l1 = lambdaFactory("1", []() { cerr << "\tNest (1)" << endl; });
auto l2 = lambdaFactory("2", []() { cerr << "\tNest (2)" << endl; });
l1(); // Works ok, displays, START, 1, END
l2(); // Same here
auto dobble = lambdaFactory("Dobble", l1);
dobble(); // Display START, Inside Dobble, START,
// then crashes when trying to execute nestedFunc(), ie l1()
}
What did I get wrong in the variable scope management ? And is there any reason for this program not crashing using Apple's LLVM ?
EDIT
For the record, here is the correct lambdaFactory
after the correction suggested by T.C. :
auto lambdaFactory = [&](string title, NestedFn nestedFunc)
{
return [&, title, nestedFunc]() {
cerr << "------------ START -----------" << endl;
cerr << "Inside: " << title << endl;
nestedFunc();
cerr << "------------- END ------------" << endl;
};
};
答案 0 :(得分:2)
通过调用lambdaFactory
返回的lambda通过引用捕获nestedFunc
,但nestedFunc
是一个按值传递的函数参数,因此一旦调用它就会超出范围lambdaFactory
返回,导致悬空参考。
这个程序有没有理由不使用Apple的LLVM崩溃?
未定义未定义的行为。您也可能使用两种不同的标准库实现(Linux上的Mac / libstdc ++上的libc ++),因此在所有内容的布局方式上可能存在差异等。