project/개발 업무

l-value, r-value

lgvv 2025. 10. 23. 02:27

l-value, r-value


프로젝트 내 C, C++, objective-c, swift 코드가 존재하여 이를 분석하면서 개념 정리.

 

용어 정리

 

L-value (locator value)란?


메모리상의 위치(location) 를 가리키는 표현식.

: 대입의 왼쪽에 올 수 있는 것(항상은 아님). 변수, 배열 원소, 프로퍼티, deref(*p) 등.
: 즉, 여기에 값을 저장할 수 있음.

 

R-value (read value / right value)란?

 

실제 값(리터럴, 계산 결과, 일시적인 임시객체).

: 보통 대입의 오른쪽에 오는 것. 임시값이므로 주소를 갖지 않거나 곧 사라짐.
: 즉, 이건 읽을 수는 있지만, 직접 이곳에 값을 저장할 수는 없다.

 

** 참고 ** 

: 현대 언어는 이분법을 확장.

: 예: C++의 xvalue/prvalue/glvalue 같은 카테고리.

 

 

R-Value와 L-Value에 대해서 간단히 정리하자면

  • 할당 가능성(assignment) 을 결정.
  • 참조/포인터/참조자를 만들 때 안전성 (참조가 유효한 메모리를 가리키는지) 판단에 영향.
  • 임시값(lifetime) 관리와 관련된 버그 (예: dangling reference, use-after-free) 방지.
  • 최적화 / 이동 시맨틱스 이해: 임시값을 이동(steal)할 수 있는지 여부가 다름.



C / Objective-C

  • 변수, 배열, *p 등은 l-value.
  • 리터럴(42, "hello")과 산술식(a + b)은 r-value.
int a = 1;    // 'a'는 l-value, '1'은 r-value
a = 2;        // ok
(a + 1) = 3;  // error: (a+1)은 r-value, 할당 불가

 

C++ 

C++11 이후 값 카테고리가 더 세분화

  • glvalue: 일반화된 lvalue (객체 또는 함수의 식별자 등).
  • prvalue: "pure rvalue", 주로 임시 객체/리터럴.
  • xvalue: expiring value — "이동 대상"인 rvalue (예: std::move(obj)의 결과).
  • lvalue는 glvalue의 한 부분.

이 분류는 이동(move)와 복사(copy)를 구분할 수 있게 해주며, 최적화와 소유권 이전에 핵심.

std::string s = "hello";       // s : lvalue
std::string t = s;             // 복사 (lvalue -> rvalue context)
std::string u = std::move(s);  // move (xvalue)

 

lvalue 메모리 위치를 가리키는 식별자 가능 변수 a, 배열 요소 arr[0]
rvalue 임시값, 대입의 오른쪽 3, a + b, 함수 반환 임시
prvalue pure rvalue (순수 임시값) 리터럴, 계산 결과
xvalue expiring rvalue (이동 가능) std::move(obj)
glvalue generalized lvalue (lvalue + xvalue 포함) -

 


Swift

Swift context에서 전통적인 C 스타일 용어가 그대로 등장하지만 Swift 고유 개념(값/참조 타입, 소유권 모델)이 있음.

  • var x = 1 → x는 l-value 성격을 가짐(할당 가능).
  • 리터럴, 계산식은 r-value.
  • inout 파라미터는 함수가 내부에서 변수의 주소(또는 식별자) 를 직접 조작하므로 l-value가 요구됨.
  • Swift는 안전성을 위해 일부 경우 임시값에 대한 주소 접근을 허용하지 않거나 trap(런타임 에러) 발생시킴.
var a = 10
a = 20        // ok (a는 l-value)
let x = a + 1 // (a+1)은 r-value
func foo(_ x: inout Int) { x += 1 }
foo(&a)       // inout은 l-value 필요

 

런타임/컴파일러 관점

  • 컴파일러는 식의 값 카테고리를 분석해 코드를 생성 (load/store, move/copy).
  • 최적화: 컴파일러는 불필요한 복사(retain/release 등)를 제거하려고 객체의 생명주기(when to retain/release)를 조정.
  • 언어 런타임은 임시값의 lifetime을 관리하고, 잘못된 접근(예: unowned 이후 접근)을 검사하여 trap 또는 crash를 발생시킬 수 있음.

 

 

(참고)

https://learn.microsoft.com/ko-kr/cpp/c-language/l-value-and-r-value-expressions?view=msvc-170

 

L-Value 및 R-Value 식

자세한 정보: L-Value 및 R-Value 식

learn.microsoft.com

https://dydtjr1128.github.io/cpp/2019/06/10/Cpp-values.html

 

C++ Values(lvalue, rvalue, xvalue, prvalue, glvalue) - dydtjr1128's Blog

C++ Values 1. Intro 우측값 참조(Rvalue reference)는 C++11에서 처음 소개된 기능으로 다소 이해하기 어려운 구조를 가지고 있다. 기존...

dydtjr1128.github.io