2013-04-16 2 views
4

VS2010에서이 코드를 실행할 때 NRVO가 적용되지 않습니다.왜 NRVO가 여기에 적용되지 않습니까?

#include <stdio.h> 

class A 
{ 
    public: 

    A() { printf("I am in constructor\n"); } 
    A(const A& a) { printf("I am in copy constructor\n"); } 
    ~A() { printf("I am in destructor\n"); } 
    int i;  
}; 

A f(int j) 
{ 
    A a; 
    if (j) return a; 
    a.i = j; 
    return a; 
} 

int main() 
{ 
    A a; 
    a = f(5); 
} 

편집 : 이것은 소멸자와 관련이 있습니다. 내가 그 라인을 주석 처리 할 때 NRVO가 사용됩니다. 근데 왜 이래?

+3

어떤 최적화 수준을 사용하고 있습니까?또한 단일 반환이있는 경우 NRVO를 적용하는 것이 훨씬 간단하며,이 경우에는 'if'를 'trivial'로 대체하는 것이 더 간단합니다. 'if (! j) ai = j;'그러면 적용 가능성이 높아집니다 . –

+0

여기를보십시오, http://msdn.microsoft.com/en-us/library/ms364057%28v=vs.80%29.aspx NRVO의 한계가 있습니다. 최적화가 활성화되어 있습니까? – kassak

+0

@ DavidRodríguez-dribeas 모든 최적화 옵션을 시도해 본 결과는 같습니다. – Belloc

답변

3

NRVO가 여기에 적용되지 않는 이유는 무엇입니까?

당신이 VC10이 알고리즘 다음이 질문에 대답 할 수있는 유일한 사람이 안정적으로 VC10가 내부적으로 어떻게 작동하는지 알고있는 사람들이다, NRVO을 수행할지 여부를 결정하는 방법을 알고 싶어요 당신의 순수한 호기심, 그리고 경우 - 그 누가 썼니.

컴파일러 에 따르면 C++ 11 표준에 따르면은 NRVO를 수행 할 수 있으며 컴파일러의 결정이 아니라 유효성 제약 조건 때문입니다. 단락 12.8/31 단위 :

[...] 복사본 생략라는 복사/이동 작업이 생략는 ( 여러 장을 제거하기 위해 결합 될 수도있다)는 다음과 같은 경우에 허용된다

- 반환 형식이 인 함수에서 return 문에 표현식이 비 volatile 자동 객체 (함수 또는 catch 절 매개 변수 제외)의 이름이고 동일한 형식 인 유형 인 경우 함수 반환 유형으로 복사/이동 작업을 생략 할 수 있습니다. 자동 객체 di rectly

[...]

그러나 함수의 반환 값으로 당신은 당신이 NRVO을 수행 할 수 컴파일러 수 있어야 기대와 요구하는 경우, 다음 대답은 " 당신은 "이 될 수 없습니다."

NRVO를 적용할지 여부는 컴파일러의 재량에 달려 있습니다. 당신은 그것에 의지 할 수없고, 당신은 그것에 의지 할 수 없다 는 실행되고 있지 않다. 이것은 내가 아는 한, "as-if"규칙에 대한 유일한 예외입니다.

이것은 NRVO가 수행 될 확률이 높기 때문에 최적화 수준을 높이면이됩니다.

+0

여기에 왜 적용되지 않는지 궁금합니다. – Belloc

+0

@ user1042389 : 좋습니다. 이 경우 대답을 얻는 것이 어려울 것입니다. 내가 말할 수있는 것은 C++ 표준이 NRVO를 허용하므로 응답이 "허용되지 않았기 때문에"가 아니라는 것입니다. –

0

나는 당신이 당신의 환경에서 무엇을보고 모르겠지만,이 (예를 들어 see here) GCC 예상 작품과 같이

일반 :

I am in constructor 
I am in constructor 
I am in destructor 
I am in destructor 

-fno-elide-constructors으로 :

I am in constructor 
I am in constructor 
I am in copy constructor 
I am in destructor 
I am in destructor 
I am in destructor 
+0

VS2010에서 두 번째 출력이 릴리스 빌드에서 최적화가 활성화 된 상태로 표시됩니다. – Belloc

관련 문제