[TIL]230420 - lvalue, rvalue(feat. 전위 증감 연산자, 후위 증감 연산자)

insightp25·2023년 4월 20일

성능면에서 전위 증감 연산자와 후위 증감 연산자는 어떤 차이가 있을까?


성능상의 차이

전위 증감 연산자(예: ++i)와 후위 증감 연산자(예: i++)는 '임시 객체에 값을 보관하는 추가과정'이 있고 없고에서 차이가 있다.

  • ++i에서는 원본 값에 1을 바로 더해 저장 후 원본을 반환한다. 반면,
  • i++에서는 '임시 객체'에 연산이 수행되기 전의 값을 담아 반환하고 -> 이후 원본에 값에 1을 더해 저장한다.

즉, i++의 경우 임시 객체에 값을 임시로 보관하는 과정이 더해졌기 때문에, 흔히 for (i = 0; i < 10; i++)와 같은 반복문에서 그 반복 횟수가 많아질 수록 성능상 차이가 날 수 있다는 것이다.

(다만 컴파일러가 i++++i로 바꿔도 영향이 없다고 판단 시 , 자동으로 바꾸어 최적화를 해준다)


lvalue, rvalue

또한, 한가지의 차이가 더 있는데, ++i에서의 i 는 'lvalue', i++에서의 i 는 'rvalue'로 분류된다는 점이다.

// 사례 1
int main()
{
	int a(1), b(2), c(3);
    
    // OK
	a = ++b = c;
	
    return 0;
}
// 사례 2
int main()
{
	int a(1), b(2), c(3);
    
    // 컴파일 오류
	a = b++ = c;
	
    return 0;
}

위에서 사례 1의 코드는 동작하는 반면, 사례 2의 코드는 컴파일 오류를 일으킨다. 이유는 사례 1(전위 증감)의 b는 lvalue인 반면, 사례 2(후위 증감)의 b는 rvalue이기 때문이다. 각각의 정의는 다음과 같다.

  • lvalue: 가리킬 수 있는 메모리 주소를 갖는 객체("an object that has an identifiable location in memory")
  • rvalue: 가리킬 수 있는 메모리 주소를 갖지 않는 객체("an object that has no identifiable location in memory")

즉, 사례 2 b++에서의 b는 rvalue로, 가리킬 수 있는 메모리 주소를 갖지 않는 객체이고, 이 주소가 없는 임시 객체에 c값을 할당하려 했기 때문에 컴파일 오류가 나는 것이다.

시스템상 rvalue에는 당연히도 값을 할당할 수 없도록 막혀있는 것이다.🙁


여담

  • C++에서 ++등의 연산자 오버로딩을 하는 경우 컴파일러가 최적화를 해주지 않는다.
  • Java에는 연산자 오버로딩 기능이 없다.

이상, 이렇게 전위, 후위 증감 연산자에서 부터 lvalue, rvalue까지 그 관계를 알아보았습니다.


reference

profile
backend, data-streaming, AI

0개의 댓글