GCC parece capturar incorrectamente variables globales por referencia en funciones lambda, incluso cuando se especifican como 'captura por valor'. Este código se compilará e imprimir "a = 9":¿GCC captura incorrectamente variables globales por referencia en funciones lambda?
#include <iostream>
int a = 10;
int main()
{
[=]() { a = 9; }();
std::cout << "a = " << a << std::endl;
return 0;
}
Mientras que este código no se compilará:
#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;
}
Pero capturar explícitamente un mundial por su valor y luego asignar a ella le da el error:
#include <iostream>
int a = 10;
int main()
{
[a]() { a = 9; }(); // assigment of read-only object
std::cout << "a = " << a << std::endl;
return 0;
}
Estoy bastante seguro de que el error es el comportamiento correcto, ¿por qué la captura implícita elude este error? Solo estoy explorando las nuevas características de C++ 11 y accidentalmente escribí el primer fragmento de código (sin darme cuenta de que debería ser un error) y luego me sorprendí cuando las modificaciones a lo que asumí que era una variable local afectaron al global.
Dado que debe ser un error asignar una variable capturada por valor en una lambda, GCC presumiblemente utiliza una referencia a la variable para fines de optimización, al menos en este caso, y no detecta la asignación errónea .
VS2010 se comporta de la misma manera en todas las cuentas. Es inusual que dos implementaciones tengan errores exactamente de la misma manera, así que creo que esto puede no ser un error. –
Aquí no está capturando, solo se pueden capturar las variables con almacenamiento automático (y 'this'). Simplemente estás usando un global como global, nada especial sobre lambdas en este contexto. – ildjarn