GCC在lambda函数中通过引用错误地捕获全局变量? [英] GCC incorrectly captures global variables by reference in lambda functions?
问题描述
GCC似乎在lambda函数中通过引用错误地捕获全局变量,即使它们被指定为按值捕获。此代码将编译并打印a = 9:
GCC seems to incorrectly capture global variables by reference in lambda functions, even when they are specified as 'capture by value'. This code will compile and print "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;
}
但是显式地通过值捕获全局值,然后赋值给出错误:
But explicitly capturing a global by value and then assigning to it gives the error:
#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的功能,并意外写了第一段代码(不意识到它应该是一个错误),然后惊讶,当我假设是一个局部变量影响全局。
I'm pretty sure that the error is the correct behaviour -- why does the implicit capture circumvent this error? I am just exploring the new C++11 features and accidentally wrote the first piece of code (not realizing it should be an error) and was then surprised when the modifications to what I assumed was a local variable affected the global.
由于它应该是一个错误,分配给一个lambda中捕获的值变量,GCC可能使用该变量的引用进行优化,至少在这种情况下,
Since it should be an error to assign to a captured-by-value variable in a lambda, GCC presumably uses a reference to the variable for optimization purposes, at least in this case, and doesn't detect the erroneous assignment.
推荐答案
§5.1.2/ 11:
§5.1.2/11:
如果* lambda表达式(具有关联的捕获默认及其复合语句 odr- )
此
或自动存储持续时间的变量,并且odr使用的实体未被显式捕获,则odr使用的实体被称为 implicitly captured ; ...
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
不会被值隐式地捕获。
Global variables have static storage duration (§3.7.1), so the global a
will not be implicitly captured by value. Still, you can access a global variable anywhere, so
[=]() { a = 9; } ();
将全局 a
设置为9
显式地捕获全局应该是错误或UB,因为§5.1.2/ 10说
Explicitly capturing a global should be an error or UB, because §5.1.2/10 says
是使用通常的非限定名称查找规则每个这样的查找将在局部lambda表达式的范围内找到具有自动存储持续时间的变量
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.
这篇关于GCC在lambda函数中通过引用错误地捕获全局变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!