10. 표현식
10.3.4 임시 개체
임시 개체(temporary object) 는 특정 표현식의 평가 결과로 생성되고, 그 표현식의 생명 주기가 끝나면 파괴되는 개체이다.
임시 개체는 rvalue 로 분류된다.
임시 개체는 다음과 같은 상황에서 생성된다.
-> 임시 개체는 런타임에 필요한 만큼 메모리를 할당 받고 해당 범위를 벗어나면 바로 메모리를 반납한다.
리터럴 : 임시 개체는 리터럴로부터 생성될 수 있다.
함수 반환 값 : 함수가 반환하는 값이 임시 개체일 수 있다.
연산의 결과: 임시 개체는 특정 연산의 결과로 생성될 수 있다.
캐스팅 : 형 변환 시 임시 개체가 생성될 수 있다.
임시 개체의 생명 주기
표현식의 끝 : 임시 개체는 표현식이 끝날 때 파괴된다.
참조 연장 : 'const' 참조로 바인딩 된 경우, 참조의 생명 주기 동안 임시 개체의 수명이 연장된다.
C++ 17 이상인 경우 : C++17 에서는 도입된 structured binding 시 임시 개체의 수명이 연장된다.
10.4 상수 표현식
C++ 는 '상수' 에 관련 된 두 가지 의미를 제공한다.
constexpr : 컴파일 타임에 평가된다. ( C++11 에 등장, 이번 절에서 주요하게 다뤄볼 예정)
const : 해당 유효 범위에서 변경되지 않는다.
constexpr 은 컴파일러가 평가할 수 있는 표현식이다. -> constexpr 은 컴파일 타임에 알려지지 않은 변수를 사용할 수 없으므로 side effect 가 없다.
변수에 비해 상수를 좋아하는 이유
이름 있는 상수는 가독성이 높다.
변수는 변경될 가능성이 있다.
임베디드 프로그래머들은 불변 데이터를 좋아한다. -> 상수 메모리는 동적 메모리보다 저렴하고, 대부분 시스템 에러에 영향을 받지 않는다.
초기화가 컴파일 타임에 수행될 경우 멀티스레드 시스템에서는 해당 개체에 대한 경합이 일어나지 않는다.
컴파일 타임의 평가는 성능 향상을 의미한다. -> 런타임에 수만번 평가가 일어날 수도 있다.
constexpr 변수의 경우, 컴파일 타임에 평가되어 변경이 불가하다.
constexpr 함수의 경우, 컴파일 타임에 평가가 가능하다면 컴파일 타임에 동작하고, 아니라면 런타임에 동작한다. (유연성을 제공한다)
10.4.1. 기호 상수
상수 변수를 이용하는 이유는 매직 넘버(하드코딩 된 값) 을 없애고, 가독성 좋은 코드를 만들기 위해 사용된다. -> 무질서하게 사용되는 리터럴 값은 가장 성가신 유지 보수의 난관 중 하나이다. (배열의 크기를 매직넘버를 사용하게 되면 그 값을 바꾸기 위해 배열마다 일일이 매직넘버를 수정해야 한다)
10.4.2 상수 표현식에서의 const
기본적으로 컴파일 타임의 상수를 정의하는 의미에서 constexpr 이 const 보다 나은 선택이지만, 오래된 코드는 const 를 사용하는 경향이 있다.
10.5 암시적 타입 변환
정수 및 부동소수점 타입은 대입문과 표현식에서 자유롭게 뒤섞여 쓰일 수 있다. -> 가능한 경우에 언제나 변수는 암시적으로 형 변환이 이루어진다.
그러나 문제는, 값이 손실(축소) 되는 변환까지 암시적으로 이루어진다는 점에 있다.
어떤 변환이 값을 보존하려면, 값을 변환한 다음, 원래 타입으로 결과를 다시 변환해서 원래의 값을 구할 수 있어야 한다. -> 변환이 그렇게 할 수 없다면 축소 변환(narrowing conversion) 이 된다.
10.5.1 타입 승격
값을 보존하는 암시적 변환은 보통 타입 승격(type promotion) 이라고 한다.
산술 연산을 수행하기 위해 int 보다 작은 정수형 타입(char)에서 int 로 암시적 형변환이 일어나는 케이스를 볼 수 있다.
10.5.2 타입 축소
기본 타입끼리는 당혹스러울 정도로 많은 방법으로 서로 간에 암시적으로 변환될 수 있다. -> 때문에, 코드를 작성할 때 의도하지 않은 방식으로 정보를 날려버릴 수 있기 때문에, 주의해야 한다.
타입 축소는 값을 보존하지 않기 때문에, 의도치 않은 방식대로 돌아갈 수 있다.
{} 초기화 식 문법은 축소 변환을 방지한다.
Last updated