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;
}
While this code will not compile:
#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;
}
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.
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.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…