[컴][c/c++] rvalue reference 와 move semantics

rvalue 와 move / c++11 에서 rvalue 와 move

 

rvalue

rvalue 는 assignment 의 right 을 뜻한다.

int a  = b;

라는 code 가 있다면, b 가 rvalue 를 이야기 하는 것이다. 참고로, 여기서 rvalue 와 상대적인 의미로 a 를 lvalue 라고 한다. 물론 이렇게 이름이 붙은 이유는 정말 단순하게 assignment(=) 의 오른쪽에 있는 녀석들이 그런 특징을 가지고 있기 때문이다. 하지만 단순히 "= 기호 오른쪽에 있는 녀석을 뜻한다." 라는 것만으로는 rvalue 가 구체적으로 무엇을 이야기 하는지 알기 어렵다.

그런데 ref. 1 에서 rvalue 와 lvalue 를 구분 짓는 좋은 방법을 이야기 해 준다. &(address)를 사용할 수 있는지 여부로 판단하라고 한다.

int a = b;

위의 식에서 &b(b의 address) 는 의미가 있나? "있다." 그렇다면 b 는 lvalue 이다.

assignment 의 right 이 rvalue 라고 했는데 아닌가? 좀 헷갈린다. 일단 아래 식을 보자.

int a = b+c;

이 경우 &(b+c) 는 어떤 의미인가? 이 경우는 compile error 가 난다. 즉 의미가 없다. b+c 는 temporary value 이기 때문에 b+c 의 address 를 구할 수 없는 것이다. 그러므로 (b+c) 를 rvalue 라고 할 수 있다.

rvalue 는 그래서 temporary 의 뜻을 내포한다고 볼 수 있다. 우리가 =(assign) 을 사용할 때 오른쪽에 놓는 값을 생각해 보자. 오른쪽에 있는 값을 왼쪽에 넣는 것이기 때문에, 결과적으로 우리는 왼쪽(lvalue) 만 가지고 있으면 되는 것이다. 오른쪽(rvalue) 의 값을 왼쪽(lvalue) 가 가지고 있기 때문에 오른쪽을 굳이 가지고 있을 필요가 없다.

 

 

move semantics

그럼 이 rvalue 라는 개념을 이용해서 무엇을 하려고 하는 것일까? c/c++ 에서 move semantics 라는 말을 사용한다. 굳이 해석을 하자면 "move 의 개념" 정도로 해석하면 될 듯 하다. 이 move semantics 를 구현해 주기 위한 도구로 rvalue 를 만들어 낸 듯 하다. 적어도 rvalue 를 통해 move semantics 를 구현하는 것은 맞다.[ref. 2]

그럼 이 move semantics 가 무엇을 이야기 하는 것일까. 흔히 사용하는 windows explorer 에서 파일의 "복사" 와 "이동" 의 개념을 알고 있다면 move semantics 도 이해할 수 있다. move 는 말 그대로 "이동"을 하는 것이다. 이것은 std::vector 의 method 를 보면서 이해를 해 보자.

std::vector<int> v;
int a = 10;
int b = 20;

v.push_back(a); // copy
v.push_back(std::move(b)); // move

위의 코드에서

v.push_back(a)

같은 경우는 "복사"(copy) 이다. 그래서 a 도 남아있으면서, 동시에 v 에 '10' 이 생겼다. 아래처럼 2개의 '10' 이 존재하는 것이다.

 a                  v
+---------+ +--------+
| | | |
| | | |
| 10 | | 10 |
| | | |
| | | |
+---------+ +--------+

하지만,



v.push_back(std::move(b)); // move


을 보자. 이 경우 push_back() 은 move 를 구현했다. 그래서 b 의 값이 v 로 옮겨간다. 실제로 구현은 어떻게 되어 있는지 모르지만, 이것은 c/c++ 에서 shallow copy 같은 느낌이다. 다시 이야기 하면, pointer 로 address 만 바꾸는 식의 느낌이다. (물론 느낌만 그렇단 이야기이다.)


 b                  v
+---------+ +--------+
| | | |
| | | |
| XX | | 20 |
| | | |
| | | |
+---------+ +--------+

이것이 move semantics 이다.


 


 


rvalue 와  move


그렇다면 이것을 어떻게 rvalue 가 어떻게 이것을 구현하는 데 도움을 주는 지 보자.


위와 같은 code 에서 v.push_back(a) 는 기존의 우리가 사용해 오던 함수(method)이다. 그래서 그냥 a 값을 vector 안에 복사해서 넣게 된다. 이 때 호출되는 vector.push_back 는 아마도 아래처럼 lvalue reference 를 argument 로 사용할 것이다.(return type 이나 template 같은 keyword 는 잊어버리자. 이해를 위해 단순하게 설명한다.)



push_back(int& a){}


하지만 v.push_back(std::move(b)) 는 조금 다르다. move(b) 는 b 를 rvalue 로 cast 하게 된다. 즉, argument b 를 rvalue 라고 얘기해 준다. 그래서 vector 의 push_back() 함수 중 argument 가 rvalue 와 관련된 녀석을 호출되게 해 준다.



push_back(int&& b){}


위처럼 rvalue reference 를 argument 로 사용하는 함수를 호출하게 될 것이다.


이렇게 argument 의 type 을 통해서 함수가 move 가 될지 copy 가 될 지 정하게 된다. 그냥 push_back_by_copy(), push_back_by_move() 같이 함수를 따로 두는 것보다는 확실히 코드가 예쁘다. ^^;;;


이런 식으로 STL 에서는 std::move() 를 통한 move semantics 를 구현해 놓았다. 그래서 이제 c++에서 좀 더 효율적인 코드를 짜는 데 도움을 줄 것이다.[ref. 2]


 


 


설명이 많이 부족하다. 좀 더 자세한 이해를 위해서는 refereces 나 다른 자료들을 좀 더 찾아보기 바란다.


ref. 1 에서 rvalue 에 대한 개략적인 이해를 할 수 있으며, 실제 사용과 관련해서는 ref. 2 의 글을 읽는 것이 도움이 될 듯 하다.


 


 


References



  1. STL Introduction lecture links Part 9 (rvalue references), channel 9, MS, 2010년 11월 29일
  2. Move semantics and rvalue references in C++11, cprogramming.com

댓글 없음:

댓글 쓰기