【发布时间】:2013-09-27 18:40:51
【问题描述】:
给出以下示例代码:
int main()
{
int i;
auto f = [=]()mutable->int*
{
return &i;
};
return 0;
}
- g++ v.4.8.1 警告“返回局部变量‘i’的地址”。
- Clang v.3.2(MacOS 的 Clang)警告“堆栈内存地址 与返回的局部变量“i”相关联”。
- VS2012 和 VS2013 RC 均未发出任何警告。
我对 lambdas 的理解是编译器会生成一个仿函数类。该仿函数类将具有所有复制变量的成员(示例中为i)。我相信在我的代码上下文中,只要f 存在,返回其成员之一的地址是安全的。在我看来,所有编译器都弄错了。我认为在f 超出范围后使用f 的成员i 的地址的警告是有效的,但是关于“局部变量'i'”的警告是不正确/具有误导性的。我说的对吗?
【问题讨论】:
-
你可以制作
istatic。 -
仿函数类将引用“i”,但“i”本身仍然只是堆栈上的一个局部变量。一旦 main() 返回,i 就不再存在了。
-
@joeking 他在询问错误,例如,即使代码完全相同,您也不会收到相同的错误:
struct S { int* operator()() { return &i; } int i; } f; -
@joeking 你能详细说明一下吗?他正在按值(
[=])捕获i,那么为什么会有参考?此外,在main()返回后,没有人争辩说这一切都超出了范围。 -
我也认为这段代码有未定义的行为,因为你复制
i而不初始化它:(