GCC在lambda函数中通过引用错误地捕获全局变量
GCC incorrectly captures global variables by reference in lambda functions?
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:
如果*lambda表达式(具有关联的捕获默认值,并且其复合语句odr使用(3.2)
this
或具有自动存储持续时间的变量,并且odr使用的实体未显式捕获,则称odr使用实体为隐式捕获。。。
全局变量具有静态存储持续时间(§3.7.1),因此全局a
不会被值隐式捕获。尽管如此,您可以在任何地方访问全局变量,因此
[=]() { a = 9; } ();
将如预期的那样将全局CCD_ 3设置为9。
明确捕获全局应该是一个错误或UB,因为§5.1.2/10说
捕获列表中的标识符使用非限定名称查找的常用规则进行查找(3.4.1.);每个这样的查找将找到在局部lambda表达式的到达范围中声明的具有自动存储持续时间的变量。
相关文章:
- 跨多个类的全局变量而不会出现重定义错误?
- C++ 给出编译器错误,将一个(静态)常量全局变量设置为另一个静态常量变量
- 在VS代码中使用全局变量时出现"undefined reference to"错误
- GUI QT全局变量错误
- 全局变量错误C
- 将大小设置为结构类型全局变量时发生编译器错误
- 全局变量和链接器错误
- 使用全局变量给出错误
- Seg 错误 - 将变量传递给方法会更改全局值
- 多个源文件中的外部全局变量未解决的链接器错误
- 包含文件会导致全局变量出现多个定义错误
- GCC在lambda函数中通过引用错误地捕获全局变量
- c++中的全局变量错误LNK2020
- c++错误:对全局变量和对象数组使用未声明的标识符
- 全局变量如何在销毁时产生错误,而局部变量却不会
- 头文件中的全局变量导致c++重定义错误
- 共享库中全局变量初始化时出现分段错误
- 分割错误在两个浏览器插件具有相同的全局变量
- 如何在循环外打印总和?我认为全局变量和局部变量的减速存在一些错误
- 当全局变量在头文件中声明为静态时,没有链接器错误