GCC는 '값으로 캡처'로 지정되어 있어도 람다 함수에서 참조로 전역 변수를 잘못 캡처하는 것으로 보입니다. 이 코드는 컴파일 및 인쇄 "는 = 9"됩니다GCC가 람다 함수에서 참조로 전역 변수를 잘못 캡처합니까?
#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는 최적화를 위해 변수에 대한 참조를 사용합니다 (적어도이 경우에는). 잘못된 할당을 감지하지 못합니다 .
VS2010는 모든 계정에 동일한 방식으로 동작 말한다 때문에
명시 적으로 글로벌 오류 또는 UB해야 캡처. 두 가지 구현이 정확히 같은 방식으로 버그가있는 것은 드문 일이므로 버그가 아닐 수도 있습니다. –
여기에서는 전혀 캡처하지 않고 있습니다 - 자동 스토리지가있는 변수 만 캡처 할 수 있습니다 (및'this'). 당신은 글로벌을 글로벌로 사용하고 있습니다.이 맥락에서 람다에 관해 특별한 것은 없습니다. – ildjarn