시작하기 전에
표준에 정의된 각 value들을 짧게 알아보는 수준으로 작성하였습니다.
본문은 MSDN의 Lvalues and Rvalues (C++)를 번역과 일부 재편집을 하였습니다.
evaluation는 평가라는 뜻입니다. 이 글에서는 값을 결정한다는 의미로 두고 따로 번역하지 않겠습니다. (값 결정 단계 정도로 이해하시면 좋겠습니다.)
일반적으로 각 value는 glvalue처럼 씁니다. 여기서는 gl-value와 같이 표기했습니다.
예제 코드는 연산자 오버로드가 없는 경우에 대한 것입니다. 연산자를 오버로드하면 value 카테고리가 바뀔 수 있습니다.
Value Categories
모든 C++ 표현식(expression)은 type과 value category에 속합니다. value category는 임시 객체를 생성, 복사 및 이동할 때 컴파일러가 따라야 하는 기본 규칙입니다.
C언어의 l-value와 r-value 개념에서 출발하여 좌측값(left-value)와 우측값(right-value)로 번역되곤 합니다만, C++ 표준의 발전에 따라 용어를 번역 없이 그대로 이해하는 것이 좋습니다. 각 value의 정의는 표준 문서 혹은 여기(cppreference.com)를 참조하시면 됩니다.
C++ 표현식 value 카테고리 구성
gl-value
Evaluation에서 객체, 비트 필드 또는 함수의 ID를 결정하는 표현식입니다.
x-value
자원을 재사용 할 수 있는 객체 또는 비트 필드를 나타내는 gl-value입니다.(일반적으로 수명이 거의 다했기 때문입니다.)
x-value 표현식에는 더 이상 접근 할 수 없는 주소가 있지만 r-value 참조를 초기화하여 표현식에 접근 할 수 있습니다. 여기에는 r-value 참조를 반환하는 함수 호출과 배열 또는 개체가 r-value 참조 인 배열 첨자, 멤버 및 멤버 식에 대한 포인터가 포함됩니다.
pr-value
Evaluation에서 객체 또는 비트 필드를 초기화하는 표현식입니다. 혹은 상황에 따라 연산자의 피연산자 값을 계산합니다.
pr-value 표현식에는 접근 할 수있는 주소가 없습니다. pr-value 표현식의 예로는 리터럴, 비 참조 유형을 리턴하는 함수 호출 및 표현식 evalution 중에 만들어지나, 컴파일러만 접근 할 수 있는 임시 개체(object)가 있습니다.
r-value
pr-value 또는 x-value입니다.
l-value
x-value가 아닌 gl-value입니다.
l-value에는 접근 할 수 있는 주소가 있습니다. l-value 표현식의 예로는 const 변수, 배열의 요소, l-value 참조를 리턴하는 함수 호출, 비트 필드, 공용체 및 클래스 멤버를 포함한 변수 이름이 있습니다.
코드 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// lvalues_and_rvalues2.cpp
int main()
{
int i, j, *p;
// 올바름: 변수 i는 l-value이고 리터럴 7은 pr-value입니다.
i = 7;
// 잘못됨: 왼쪽 피연산자는 l-value여야 합니다.
// ` * 4`는 pr-value입니다.
7 = i; // C2106
j * 4 = 7; // C2106
// 올바름: 역참조 포인터(the dereferenced pointer)는 l-value입니다.
*p = i;
// 올바름: 조건부 연산자는 l-value를 반환합니다.
((i < 3) ? i : j) = 7;
// 잘못됨: 상수 ci는 수정할 수 없는 l-value입니다.
const int ci = 7;
ci = 9; // C3892
}
추가로 읽기 좋은 글
본문의 내용이 매끄럽지 못한 것 같아 덧붙여 읽으시면 도움이 될 글을 링크로 남깁니다.
모두의 코드 ~ 씹어먹는 C++ - <16 - 3. 타입을 알려주는 키워드 decltype 와 친구 std::declval>