본문 바로가기
카테고리 없음

[C++] L-value & R-vlaue

by MY블로그 2023. 4. 21.

기초 공부할때 Lvalue & Rvalue는 Left-value(왼쪽값), Right-value(오른쪽값)으로 이해하고 있었습니다.

( 연산자 ( = ) 를 기준으로 왼쪽에있다면 lvalue, 오른쪽에있다면 rvalue )

기본 C언어에서의 개념은 위처럼 볼 수 있더라도 C++에서는 좀더 확장적인 의미를 가지고 있어 정리를 해보도록 한다.

 

C++에서의 Lvalue, Rvalue 의 구분

우선 C++에서 모든 표현식은 Lvalue 또는 Rvalue 로 구분 됩니다.

Lvalue는 단일 표현식 이후에 사라지지 않고 계속 남아있는 객체를 의미 합니다.

이와 반대로 Rvalue는 표현식 이후에 더이상 존재하지 않는 임시적인 값을 의미 합니다.

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

위의 코드에서 밑줄로 표현되어 있는 부분들이 Rvalue 입니다.

x, y, z, p 등의 변수 이름들은 모두 Lvalue 이지만 3처럼 이름이아닌 상수혹은 임시객체 string("one") 은 표현식이 종료된후 더이상 참조할 수 없기 때문에 Rvalue 입니다.

마찬가지로 x+y, &x 또한 표현식이후 참조할 수 없는 Rvalue 입니다.

 

여기서 유심하게 보아야 할 부분은 전위증감, 후위증감 에 대한 값 입니다.

전위증감 ++x 는 Lvalue 이지만

후위증감 x++ 는 Rvalue 입니다.

 

증감 위치에 따라 Lvalue, Rvalue가 변하는 이유는 전위증감은 우선 ++를 사용하여 증가된 결과 값을 리턴 시키고난뒤 표현식을 실행하기떄문에 Lvalue 입니다.

 

반대로 후위증감의 경우 연산된 x본인이 아닌 연산후의 ++된 x를 복사하여 반환하기 때문에 Rvalue 입니다.

 

C++에서의 Lvalue Reference

위처럼 대략적으로 보았을때 Lvalue 인지 Rvalue 인지 모르는 경우도 있을 것 입니다.

그런경우 & 연산자를 사용하여 확인이 가능합니다.

&연산자는 Lvalue를 요구하기 때문에 표현식이 Rvalue일 경우 컴파일 오류를 반환합니다.

&(++x); // Lvalue 정상 작동
&(x++); // Rvalue 컴파일 오류!

기본적으로 사용하는 int& a = b; 의 형태의 사용법에서 참조자는 Lvalue 참조자 입니다.

즉, 좌측값(Lvalue)는 어떠한 메모리 위치를 가리키는데, & 참조연산자를 통하여 그 위치를 참조할 수 있는 것입니다. 

 

C++에서의 Rvalue Reference

Visual Studio 2010 이상의 버전에서는 참조자 &&를 사용하여 Rvalue 참조자를 사용할 수 있습니다.

Rvalue Reference는 사용할때 타입에 &&를 붙여 사용합니다.

이름 그대로 Rvalue에 대한 참조를 가능하게 해줍니다.

우측값 참조가 왜 사용되는지에 대한 이유는 대표적으로 두가지를 볼 수 있습니다.

  1. move 의 구현 (move semantics)
  2. 와벽 전달 (perfect forwarding)

 

#include <iostream>
#include <string>

std::string& GetStringAddress(std::string&& String)
{
	std::cout << "Address Of Param Instance On Function Stack : " << &(String) << std::endl;
	return String;
}

int main()
{
	std::string Hello = "Hello";
	std::string World = " World!";

	std::string&& HelloWorld = (std::string&&)GetStringAddress(Hello + World);
	//rvalue reference를 수행하기를 원한다.
	//Hello + World의 결과 값이 저장된 스택영역에 대해 정리X

	std::cout << "Address Of Rvalue In Stack : " << &HelloWorld << std::endl;

}

위의 코드를 예시로보자면 기존에 Rvalue는 연산후 사라지게되는 것으로 알고있었으나 참조를 이용하여 사라지지않고 남아있는 모습을 볼 수 있습니다.

 

우측값 연산자에대한 상세한 예시는 다른 블로그를 한번 더 참조하도록 합니다.

아래의 블로그가 아주아주 상세하기때문에 몇번 정독해야 할 듯 합니다!

https://modoocode.com/189

 

씹어먹는 C++ 토막글 ① - Rvalue(우측값) 레퍼런스에 관해

 

modoocode.com

 

댓글