提问者:小点点

返回lambda时的Clang警告-捕获lambda


下面尝试包装lambda的(简化的)代码给了我一些Clang版本的警告,但不是所有版本,也不是gcc版本。

template<typename Lambda>
auto wrapLambda(Lambda lambda)
{
    return [&lambda]() {
        lambda();
    };
}

auto wrappedLambda = wrapLambda([](){ return 0; });
warning: address of stack memory associated with parameter 'lambda' returned [-Wreturn-stack-address]  
    return [&lambda]() {  
             ^~~~~~

这是一个窃听器,还是我遗漏了什么?我在godbolt和clang 11.1.0版本中收到了x86-64 clang(trunk)的警告,这是一个更大的回购的一部分,但我还无法隔离该版本的故障。

这个相关问题中的例子没有给出警告。

改进(我认为)版本:

template<typename Callable>
auto wrapCallable(Callable&& callable)
{
    return [callable = std::forward<Callable>(callable)]() {
        callable();
    };
}

auto wrappedCallable = wrapCallable([](){ return 0; });

这将使Godbolt中的x86-64 clang(trunk)的警告沉默。我想它应该能安全地适用于任何一个functor,任何我遗漏的东西?


共1个答案

匿名用户

问题与此代码完全相同:

SomeType& foo(int x)
{
    SomeType bar{x};
    return bar; // undefined behavior returning reference to local object
}

lambda是通过引用捕获本地对象的,所以当您返回它时,这将导致未定义的行为,因为捕获的对象不再存在。

当你使用这个lambda时,程序很可能会崩溃(如果你不走运的话就不会崩溃)。

所以这是你代码中的bug,clang是正确的抱怨。