【发布时间】:2021-04-18 15:52:04
【问题描述】:
为什么这段代码运行不正确? 参见函数“f1”。它将“t”分配给 std::function。我列出了 3 种方法来做到这一点。但是第一个是错误的。它会输出不正确的值。如果代码复杂,程序甚至可能崩溃。我已经知道原因是 lambda "t" 是一个局部变量,所以我们必须按值捕获它。但是这样的代码可以在没有错误或警告的情况下编译,有没有办法(任何编译选项?)在编译时找到这样的错误?
#include <iostream>
#include<functional>
struct aa
{
int a = 2000;
void f()
{
++a;
printf("data = %d\n", a);
}
};
std::function<void()> gf;
template<typename T>
void f1(T t)
{
1 //gf = [&] {t(); };
2 //gf = [=] {t(); };
3 //gf=t;
}
int main(int argc, char** argv)
{
aa b2;
f1([&] {b2.f(); });
gf();
return 0;
}
在线测试:https://godbolt.org/z/5bqGeof58
更新:最新的clang可以检测非常简单的情况,但不适用于上面的代码。 示例:
auto f(int a)
{
return [&]{return a;}; //warning: address of stack memory associated with parameter 'a' returned [-Wreturn-stack-address]
}
int main(int argc, char** argv)
{
printf("%d\n",f(300)());
return 0;
}
【问题讨论】:
-
一般来说,C++ 编译器很难在编译时发现这些问题。考虑使用 asan 和 msan 在运行时通过单元测试更好地发现这些问题。