【发布时间】:2020-07-07 18:04:54
【问题描述】:
我发现如果我使用 lambda 通过 mutable 关键字捕获对全局变量的引用,然后修改 lambda 函数中的值,则不同编译器的结果会有所不同。
#include <stdio.h>
#include <functional>
int n = 100;
std::function<int()> f()
{
int &m = n;
return [m] () mutable -> int {
m += 123;
return m;
};
}
int main()
{
int x = n;
int y = f()();
int z = n;
printf("%d %d %d\n", x, y, z);
return 0;
}
VS 2015 和 GCC (g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609) 的结果:
100 223 100
clang++ 的结果(clang 版本 3.8.0-2ubuntu4 (tags/RELEASE_380/final)):
100 223 223
为什么会这样? C++ 标准是否允许这样做?
【问题讨论】:
-
Clang 的行为仍然存在于主干上。
-
这些都是相当老的编译器版本
-
它仍然出现在最新版本的 Clang 中:godbolt.org/z/P9na9c
-
如果您完全删除捕获,那么 GCC 仍然接受此代码并执行 clang 所做的操作。这强烈暗示存在 GCC 错误 - 简单捕获不应该改变 lambda 主体的含义。
标签: c++ c++11 lambda language-lawyer