ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RVO, NRVO
    개발/C·C++ 2022. 1. 8. 17:10

    NRVO는 프로젝트 속성 페이지의 C/C++의 최적화 탭에서 최적화 항목을 최적화라고 선택해야 동작합니다. 속도 우선이나 크기 우선 옵션으로 해도 됩니다. 최적화 옵션을 키고 나서 RTC1 옵션과 충돌을 일으킨다는 메시지가 뜨면 C/C++의 코드 생성 탭에서 기본 런타임 검사 옵션을 기본값으로 설정합니다. NRVO가 동작하면 다음 코드는 객체 복사를 수행하지 않습니다.

    #include <iostream>
    using namespace std;
    
    class Test
    {
    public:
    	Test() : _num(0)
    	{
    		cout << "Constructor" << endl;
    	}
    
    	Test(int num) : _num(num)
    	{
    		cout << "Constructor : " << _num << endl;
    	}
    
    	Test(const Test& rhs)
    	{
    		cout << "Copy " << rhs._num << " >> " << _num <<endl;
    		_num = rhs._num;
    	}
    
    	Test(Test&& rhs) noexcept
    	{
    		cout << "Move " << rhs._num << " >> " << _num << endl;
    		_num = rhs._num;
    	}
    
    	~Test() 
    	{
    		cout << "Destructor : " << _num << endl;
    	}
    
    	friend ostream& operator<<(ostream& os, Test& t)
    	{
    		return os << "overloading " <<t._num;
    	}
    
    private:
    	int _num;
    };
    
    Test func()
    {
    	Test t;
    	return t;
    }
    
    int main()
    {
    	Test t = func();
    }

     

    RVO는 임시 객체를 반환하거나 함수의 파라미터로 넘기면 객체 복사를 수행하지 않는 것입니다. 이 부분의 코드는 생략하겠습니다.

     

    다음 코드를 수행하면 로그가 어떻게 나올까요? t1, t2 객체는 어차피 함수 종료와 함께 소멸되므로 move 함수로 리턴해줘야 할까요?

    Test testFunc()
    {
    	Test t1(1);
    	Test t2(2);
    
    	int i = 0;
    	cin >> i;
    	if (i < 0)
    		return t1;
    	else
    		return t2;
    }
    
    int main()
    {
    	Test result = testFunc();
    	cout << "---------------" << endl;
    	cout << result << endl;
    }

    컴파일러는 알고 있습니다. 그래서 자동으로 move 생성자를 호출해줍니다. 여기서 신기한 점은, 아직 정확한 이유는 파악하지 못했습니다만, result 객체에 1이 할당되어 있다는 점입니다. 중단점을 찍어 보면 if(i < 0) 분기를 타고 들어갑니다. 로그에는 안 나왔지만 t1의 값이 들어가있는 것으로 추정됩니다. 어셈블리 파일을 봤지만 아직은 제대로 된 이유를 모르겠습니다.

     

    중요한 부분은 move 생성자를 컴파일러가 알아서 호출해줬다는 것입니다.

    '개발 > C·C++' 카테고리의 다른 글

    shared_ptr 사용할 때 주의 사항  (0) 2022.01.09
    전달 참조(보편 참조)  (0) 2022.01.08
    constexpr  (0) 2022.01.06
    noexcept  (0) 2022.01.06
    객체 생성 시 const의 위치 차이  (0) 2022.01.04

    댓글

Designed by Tistory.