l-value 와 r-value 의 유래
l-value 와 r-value 는 대입식(assignment)의 대입 연산자(=) 양측의 위치에 따른 이름입니다.
- l-value (left hand side value, lhs) 는 대입 연산자의 왼쪽 혹은 오른쪽에 올 수 있는 값.
- r-value (right hand side value, rhs) 는 대입 연산자의 오른쪽에 오는 값.
++number = 20 + addVal - 3;
위의 코드는 대입 식이라는 표현식 (expression) 아래, = 를 기준으로 하위 표현식을 가지고 있습니다. 위 식에서 대입식이 상위 표현식이 되는 이유는, 연산자 우선순위상 계산 순서에 따라 대입식이 가장 마지막에 처리되기 때문입니다.
left expr: ++number
right expr: 20 + addVal - 3;
left expr 은 모든 연산이 끝나면 최종적으로 number 라는 개체가 됩니다.
대입연산자의 좌측 표현식의 결과에는 대입 받을 수 있는 무엇인가가 남아야 합니다.
right expr 은 모든 연산이 끝나면 17에 addVal 을 더한 값 혹은 개체가 됩니다.
이 표현식의 결과 값은 좌측 표현식의 결과에 대입을 해 주고 나면 그 뒤는 필요 없습니다.
l-value 와 r-value 의 정의
l-value 는 반드시 명시적인 메모리 공간을 가져야 합니다. 값이나 개체를 대입 받기 때문입니다.
그러나 r-value 는 잠깐 사용하고 사라지는 임시적인 값으로, 잠시 유지해서 l-value 에 값을 전해줄 수 있으면 충분합니다.
이에 r-value 는 '임시 값'에 대한 통칭이 됩니다.
int value = 20;
이 코드는 허용됩니다. 20은 상수이며, '임시 값' 이고, r-value 이기도 합니다.
- 상수의 경우 기계어로 번역시 명령어에 그대로 포함되며, 코드 영역의 일부가 됩니다.
20 = value;
따라서 '임시 값'에 대입하는 위와 같은 코드는 허용되지 않습니다.
int value = 20;
value = 20 + value;
두 번째 value 에 대한 대입문이 동작할때, 연산자 우선순위에 따라 20 + value 가 먼저 처리됩니다.
그리고 이 20+ value 라는 값은 새로운 '임시 값', r-value 가 되어 l-value 인 value 에 대입됩니다.
이 임시 값은 이 대입 식이 끝나면 사라집니다.
l-value 와 r-value 의 차이점
l-value 와 r-value 의 가장 큰 차이점은 바로 이름입니다.
- l-value 는 이름에 의해 프로그래밍으로 제어할 수 있습니다.
- r-value 는 이름이 없습니다. 내부적으로 사용되고, 내부적으로 사라집니다. 프로그래밍으로 제어할 수 없습니다.
단, r-value reference 에 의해 l-value 처럼 접근할 수 있는 방법은 존재합니다.
After C++11
C++11 이 등장하면서, l-value 와 r-value 는 더 상세한 구별을 가지게 되었습니다.
- Primary Category
- lvalue : identity (이름) 을 가지고 있으며, move 될 수 없음.
- xvalue : identity (이름) 을 가지고 있으며, move 될 수 있음.
- prvalue : identity (이름) 이 없고, move 될 수 있음.
- Mixed Category
- rvalue : prvalue or xvalue
- glvalue : lvalue or xvalue
정확한 분류 조건은 cplusplus.com 를 참조해주세요.