use*_*938 13 c++ lambda gcc c++11
GCC似乎错误地通过lambda函数中的引用捕获全局变量,即使它们被指定为"按值捕获".此代码将编译并打印"a = 9":
#include <iostream>
int a = 10;
int main()
{
[=]() { a = 9; } ();
std::cout << "a = " << a << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
虽然这段代码不会编译:
#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;
}
Run Code Online (Sandbox Code Playgroud)
但显式捕获全局值然后分配给它会产生错误:
#include <iostream>
int a = 10;
int main()
{
[a]() { a = 9; } (); // assigment of read-only object
std::cout << "a = " << a << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我很确定错误是正确的行为 - 为什么隐式捕获会绕过这个错误?我正在探索新的C++ 11功能,并意外地编写了第一段代码(没有意识到它应该是一个错误),然后当我假设的局部变量的修改影响了全局时,我感到很惊讶.
由于分配给lambda中的值捕获变量应该是一个错误,因此GCC可能会使用对变量的引用进行优化,至少在这种情况下,并不会检测到错误的赋值.
ken*_*ytm 24
§5.1.2/ 11:
如果*lambda表达式(具有关联的capture-default及其复合语句 odr-uses(3.2)
this
或具有自动存储持续时间的变量且未明确捕获使用了odr的实体,则表示使用了odr的实体被隐含地捕获 ; ......
全局变量具有静态存储持续时间(第3.7.1节),因此a
不会通过值隐式捕获全局变量.不过,您仍可以在任何地方访问全局变量
[=]() { a = 9; } ();
Run Code Online (Sandbox Code Playgroud)
将按a
预期将全局设置为9.
明确捕获全局应该是错误或UB,因为§5.1.2/ 10说
该标识在捕获列表中查找使用不合格的名称查找的一般规则(3.4.1); 每个这样的查找应该找到一个变量,其自动存储持续时间在本地lambda表达式的到达范围内声明.
归档时间: |
|
查看次数: |
3267 次 |
最近记录: |