GCC 似乎在 lambda 函数中通过引用错误地捕获全局变量,即使它们被指定为“按值捕获”。此代码将编译并打印“a = 9”:
#include <iostream>
int a = 10;
int main()
{
[=]() { a = 9; } ();
std::cout << "a = " << a << std::endl;
return 0;
}
虽然这段代码不会编译:
#include <iostream>
int main()
{
int a = 10;
[=]() { a = 9; } (); // error: assignment of member 'main()::<lambda()>::a' in read-only object
std::cout << "a = " << a << std::endl;
return 0;
}
但是通过值显式捕获全局然后分配给它会产生错误:
#include <iostream>
int a = 10;
int main()
{
[a]() { a = 9; } (); // assigment of read-only object
std::cout << "a = " << a << std::endl;
return 0;
}
我很确定这个错误是正确的行为——为什么隐式捕获会绕过这个错误?我只是在探索新的 C++11 特性,不小心写了第一段代码(没有意识到这应该是一个错误),然后当我认为是局部变量的修改影响了全局时,我感到很惊讶。
由于在 lambda 中分配给按值捕获的变量应该是错误的,因此 GCC 可能会出于优化目的使用对该变量的引用,至少在这种情况下,并且不会检测到错误的分配。
最佳答案
§5.1.2/11:
If a *lambda-expression( has an associated capture-default and its compound-statement odr-uses (3.2)
this
or a variable with automatic storage duration and the odr-used entity is not explicitly captured, then the odr-used entity is said to be implicitly captured; ...
全局变量具有静态存储持续时间(第 3.7.1 节),因此全局 a
不会隐式按值捕获。不过,您可以在任何地方访问全局变量,所以
[=]() { a = 9; } ();
将按预期将全局 a
设置为 9。
显式捕获全局应该是错误或 UB,因为 §5.1.2/10 说
The identifiers in a capture-list are looked up using the usual rules for unqualified name lookup (3.4.1); each such lookup shall find a variable with automatic storage duration declared in the reaching scope of the local lambda expression.
关于c++ - GCC 在 lambda 函数中通过引用错误地捕获全局变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9199744/