GCC неправильно захватывает глобальные переменные по ссылке в лямбда-функциях?

Кажется, GCC неправильно захватывает глобальные переменные по ссылке в лямбда-функциях, даже если они указаны как «захват по значению». Этот код скомпилирует и напечатает «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 и случайно написал первый фрагмент кода (не осознавая, что это должна быть ошибка), а затем был удивлен, когда изменения того, что я считал локальной переменной, повлияли на глобальную.

Поскольку присвоение переменной, захваченной по значению, в лямбда-выражении должно быть ошибкой, GCC предположительно использует ссылку на переменную в целях оптимизации, по крайней мере, в этом случае, и не обнаруживает ошибочное присвоение.

13
задан ildjarn 8 February 2012 в 20:25
поделиться