2017-10-26 1 views
2

아래 코드를 참조하십시오. 올바른 출력은 "10 20 30"이지만 Release에서는 "0 0 0"을 빌드합니다. 왜 이런 일이 생길까요?람다에서만 사용되는 경우 릴리스 빌드에서 초기화되지 않은 로컬 정적 변수

std::vector<int> inValues = {1, 2, 3}; 
    std::vector<int> outValues(inValues.size()); 

    static const int mag = 10; 

    std::transform(inValues.cbegin(), inValues.cend(), outValues.begin(), 
    [](const auto value){ 
    return value * mag; 
    }); 

    for (const auto value: outValues) 
    std::cout << value << " "; 

변수가 function 내부 어디에서나 언급되거나 전역 범위에서 선언되는 경우 모두 예상대로 작동합니다.

답변

2

람다 변수 캡처 말하기 http://en.cppreference.com/w/cpp/language/lambda#Explanation 말한다 : 그것은 자동 보관 기간이없는 경우

변수가 포착되지 않고 사용될 수있다 (이것은 로컬 변수 아니거나 정적 또는 스레드 즉 지역)

변수 입니다. 따라서 "정적 로컬"은 자동으로 캡처해야합니다. 또한 Microsoft gives this example of using a local static storage element

:

void fillVector(vector<int>& v) 
{ 
    // A local static variable. 
    static int nextValue = 1; 

    // The lambda expression that appears in the following call to 
    // the generate function modifies and uses the local static 
    // variable nextValue. 
    generate(v.begin(), v.end(), [] { return nextValue++; }); 
    //WARNING: this is not thread-safe and is shown for illustration only 
} 

귀하의 예제는하지 않지만 의도 한대로이 작업을 수행합니다.

이것은 버그입니다.에 정리 된 것으로 신고 할 수 있습니다. 따라서 이것을 버그로보고 할 수는 있지만 Visual Studio 2017로 업그레이드하는 것이 좋습니다.보고를 선택하면 여기에 버그 보고서를 링크하는 것이 좋습니다.

+1

나는 당신을 생각 : 당신이 static 규정 유지에 대한 단호 인 경우

그렇지 않으면, 당신은 너무 값이 컴파일시 멀리 최적화되지, 그것을 정의 직후 mag를 사용하는 척 수 정적 변수를 캡처 할 필요가 없습니까? – frslm

+0

@frslm 네가 맞아. 이것은 Visual Studio 버그입니다. 이스터 에그를 찾아 +1하십시오. –

+1

clang 툴셋으로 빌드를 시도했지만 완벽하게 작동합니다. 그래, 그 버그. –

1

흥미롭게도 컴파일시 mag이 0으로 설정되어 있습니다. Visual Studio는 실제로 람다 식에서 사용된다는 것을 인식하지 못합니다.

magconst int으로 만 변경할 수 있습니다. 함수에서 정의한 경우 을 static const으로 정의하면 얻을 수있는 이점은 거의 없습니다. 단 const입니다.

static const int mag = 10; 
(void)mag; // (pretend to use mag) 
+0

아니,'static const'가 우연히 여기에서 사용되었지만, 어쨌든 좋은 연습은 아닙니다. 함수 안에'mag '를 언급하면 ​​컴파일러 버그 만 숨 깁니다. –