C에서의 Rvalue, Lvalue는 좌측 값은 대입(assignment) 시에 왼쪽 혹은 오른쪽에 오는 식(expression)이고, 우측 값은 대입 시에 오직 오른쪽에만 오는 식이다.라고 정의하고 있지만 C++에서는 다음과 같이 정의하고 있다.
좌측 값은 어떠한 메모리 위치를 가리키는데, & 연산자를 통해 그 위치를 참조할 수 있다.
우측 값은 좌측 값이 아닌 값들이다.
C++11부터는 prvalue, xvalue, glvalue가 추가되었다.
C++11에서는 이러한 value들을 다음과 같이 나누었다.
lvalue : identity를 가지면서 move 될 수 없는 표현식
xvalue : identity를 가지면서 move 될 수 있는 표현식
prvalue : identity를 가지지 않고 있으면서 move 될 수 있는 표현식들
glvalue : identity를 가지고 있는 표현식들(lvalue, xvlaue 모두 glvalue 표현식)
rvalue : move 될 수 있는 표현식들(prvalue, xvalue 모두 rvalue 표현식)
identity를 가지고 있지 않으면서 move 될 수 없는 것들.
identity를 가진다 : 값이 식별성을 가지고 있다.
move 될 수 있다 : 값이 메모리에서 이동될 수 있다. 포인터가 있는 값은 주소를 이동할 수 있다.
move는 메모리 주소는 유지되면서 포인터만 변경, copy는 값을 복사하기 때문에 매번 메모리가 할당된다.
lvalue ( identity를 가지면서 move 될 수 없는 값들 )
- 대입문의 좌측에 올 수 있다.
- &연산자로 값의 주소를 얻어올 수 있다.
- 표현식이 끝나더라도 값이 살아 있다.
static int a = 10;
int& inc()
{
a++;
return a;
}
int get()
{
return a;
}
int main()
{
int a = 10, b = 10, c = 10;
int *j = &a; // 참조 가능하기 때문에 a는 lvalue
inc() = 43; // inc()는 lvalue
int* ptr = &inc(); // &inc()는 가능하기 때문에 lvalue
++a; // a는 lvalue
int C[4];
cout << C[1] << endl; // c[1]도 lavlue
a ? b : c; // 반환 값은 b or c 이므로 lvalue
return 0;
}
xvalue ( identity를 가지면서 move 될 수 있는 표현식들 )
- 컴파일러만 사용하는 객체이기 때문에 &연산자가 허용되지 않는다.
- 표현식이 끝났을 때 사라진다.
컴파일러가 필요로 하는 임시 데이터 저장 공간을 xvlaue라고 한다. std::move()와 같이 rvalue reference를 리턴할 수 있는 함수는 lvalue를 move 하고, move 한 값은 xvalue에 속하게 된다.
prvalue ( identity를 가지고 있지 않으면서 move 될 수 있는 표현식들 )
- 대입문의 우측에 올 수 있다.
- 주소가 없다.
prvalue는 pure_rvalue의 약자로 후위 증감 연산자, 문자열 리터럴을 제외한 모든 리터럴 등이 prvalue에 속한다.
int a = 10;
int b = 20;
if (a < b) // a < b의 결과 값 bool은 prvalue
{
}
glvalue ( identity를 가지고 있는 표현식들. lvalue, xvalue )
glvalue는 xvalue 혹은 lvalue를 의미한다. 쉽게 말하자면 데이터를 저장할 수 있는 메모리의 위치 정보를 가지고 있다. gvalue는 lvalue에서 rvalue로 변환이 가능한데 포인터, 배열 및 함수에서 암시적 변환을 통해 prvalue로 변환할 수 있다.
rvalue ( move 될 수 있는 표현식들. prvalue, xvalue )
rvalue는 메모리 주소에서 이동이 될 수 있는 표현식들을 통칭하는 말이다.
int& inc1(int &a)
{
a++;
return a;
}
int intc2(int& a)
{
a++;
return a;
}
inc1() 함수는 int&를 리턴하게 되는데 이는 a라는 실제 객체를 리턴 시키는 함수이며 lvalue 속성을 갖는다.
inc2() 함수는 int를 리턴하게 되는데 이는 a의 복제본을 리턴하는 것이며 rvalue로 변환된다.
'Program Language > C & C++' 카테고리의 다른 글
error C2558 : no copy constructor available or copy constructor is declared 'explicit' (4) | 2021.10.21 |
---|---|
[C++] std::async (0) | 2021.10.19 |
[C++] std::move (0) | 2021.10.08 |
[C++] packaged_task (2) | 2021.10.07 |
[C++] thread_local (0) | 2021.10.07 |