GCC在lambda函数中通过引用错误地捕获全局变量? [英] GCC incorrectly captures global variables by reference in lambda functions?

查看:641
本文介绍了GCC在lambda函数中通过引用错误地捕获全局变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆