Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

KH_C++

Lvalue, Rvalue, Lvalue Reference, Rvalue Reference 본문

공부

Lvalue, Rvalue, Lvalue Reference, Rvalue Reference

kanghou 2023. 4. 24. 03:53

[ Lvalue ]

  • 단일 식을 넘어 지속되는 개체
  • 주소가 있음
  • 이름이 있는 변수
  • const 변수
  • 배열 변수
  • 비트 필드
  • 공용 구조체
  • 클래스 멤버
  • 좌측 값 참조&로 반환하는 함수 호출
  • 문자열 리터럴

[ Rvalue ]

  • lvalue 가 아닌 개체
  • 사용되는 단일 식을 넘어 지속되지 않는 일시적인 값
  • 주소가 없는 개체
  • 리터럴 (문자열 리터럴 제외)
  • 참조로 반환하지 않는 함수 호출
  • i++, i--
  • 기본으로 지원되는 산술식, 논리식, 비교식
  • 열거형 (enum)
  • 람다(lambda)

C++ Lvalue와 Rvalue에 대한 오해

Lvalue와 Rvalue는 보통 Left-value(왼쪽값)과 Right-value(오른쪽값)로 풀어서 씁니다. 이 때문에 대입 연산자(=)를 기준으로 왼쪽에 위치하는 값이 Lvalue이고 오른쪽에 위치하는 값이 Rvalue라고 이해하고 계신 분들이 많다. 이것은 C 표준에 입각하여 살펴보면 완전히 틀린 얘기는 아니지만(C 표준에서는 대입 연산자(=)를 기준으로 왼쪽과 오른쪽에 모두 사용될 수 있는 값은 Lvalue이고 오른쪽에만 사용될 수 있는 값이 Rvalue라고 정의하고 있습니다) 잘못된 이해이며, C++ 관점에서는 전혀 다른 관점에서 해석할 필요가 있습니다.

C++ 표준에서는 더이상 에서 L과 R은 Left와 Right를 의미하지 않습니다.  Lvalue와 Rvalue를 단순히 고유명사로만 기억해야한다.

 

Lvalue와 Rvalue의 구분

C++에서 모든 표현식은 Lvalue 또는 Rvalue 입니다. Lvalue는 단일 표현식 이후에도 없어지지 않고 지속되는 객체입니다.쉽게 생각해서 이름을 가지는 객체는 Lvalue라고 얘기할 수 있죠. 그러므로 const 타입을 포함한 모든 변수는 Lvalue 입니다. 반면에 Rvalue는 표현식이 종료된 이후에는 더이상 존재하지 않는 임시적인 값입니다. 상수 또는 임시 객체는 Rvalue 라고 얘기할 수 있다. 

R value - 모든 L value는 R value지만 R value는 L value가 아닐 수 있다.

 

출처:

https://effort4137.tistory.com/entry/Lvalue-Rvalue


위 C++ 코드에서 첫줄의 val은 L value이며 R value인 상수값 20을 나타내게 되었습니다. 정확히는 val 이 가리키는 메모리 주소에 20이 들어가게 된 것이다.

 그리고 2번째 val의 경우 = 왼쪽에 있는 val은 여전히 L value이지만 20 + val은 그 자체로 (20 + val)이라는 '임시 값'이 되어 R value가 되는 것이다.

 위 코드에서는 function()이 R value가 됩니다. 이쯤되면 어느정도 예상을 해볼 수 있는데 R value는 해당 표현식이 끝나면 더이상 참조할 수 없는 값을 의미하게 된다.


[ Lvalue, Rvalue Reference ]

&, && - 기존 & 를 사용하면 L value의 참조자를 만들 수 있었습니다.

이런 식으로 L value에 대해 참조자를 만들 수 있습니다. 그런데 C++ 11에서는 &&이 추가되어서 R value에 대해서도 참조자를 만들 수 있게 된다.

 이런 식으로 하면 R value에 대해서 참조자를 만들 수 있게 된다. 


[ 전위 연산자와 후위 연산자의 동작 방식의 차이 ]

이제 전위 연산자와 후위 연산자의 차이를 알아보자.

두 단항 연산자 모두 피연산자의 값을 1 증가/감소 시키는 역할을 한다.

하지만 두 연산자의 작동 방식에 차이가 있어 다음과 같은 차이를 발생시키곤 한다.

int num = 10;
// 전위 연산자의 경우: compile error가 뜨지 않는다.
++num = 30;
// 후위 연산자의 경우: complile error! [error C2106: '=': 왼쪽 피연산자는 l-value이어야 합니다.]
num++ = 30;

오류 문구를 보면 num++은 lvalue가 아니기 때문에 num++ = 30;이 컴파일 에러가 났음을 알 수 있다.

그렇다는 것은 전위 연산자는 lvalue이고, 후위 연산자는 rvalue라는 뜻

 

출처:

https://m42-orion.tistory.com/68


간단한 예)

 

    int number = 10;                           // number는 lvalue

    int* pNumber = &number             // pNumber는 lvalue

    const int NUMBER_MAX = 20   // NUMBER_MAX는 lvalue

    const char* name = "dracula"     // name, "dracula"는 lvalue

 

    int number = 10;                           // 10은 rvalue

    10 = number;                                // 10은 rvalue이기 때문에 error 

    (number + 5) = 10;                      // (number + 5)는 rvalue이기 때문에 error

    int number2 = 20;

    int sum = number + number2;   // number + number2는 rvalue

    

    if(number < number2)                 // number < number2 는 rvalue

    

    int zero = 0;                             

    int& reference = zero;                 // reference lvalue 참조

    int& reference2 = 0;                   // 0은 rvalue, reference2 는 lvalue 참조기 때문에 error

 


 

Comments