10. 표현식

10.3.4 임시 개체

  • 임시 개체(temporary object) 는 특정 표현식의 평가 결과로 생성되고, 그 표현식의 생명 주기가 끝나면 파괴되는 개체이다.

  • 임시 개체는 rvalue 로 분류된다.

임시 개체는 다음과 같은 상황에서 생성된다.

-> 임시 개체는 런타임에 필요한 만큼 메모리를 할당 받고 해당 범위를 벗어나면 바로 메모리를 반납한다.

  1. 리터럴 : 임시 개체는 리터럴로부터 생성될 수 있다.

std::string str = "Hello";    // "Hello" 는 임시 std::string 개체로 변환된다. 
  1. 함수 반환 값 : 함수가 반환하는 값이 임시 개체일 수 있다.

std::string getString() {
    return "Temporary String";
}
std::string str = getString();     // getString() 의 반환 값은 임시 개체
  1. 연산의 결과: 임시 개체는 특정 연산의 결과로 생성될 수 있다.

std::string str = std::string("Hello") + " World";    
  1. 캐스팅 : 형 변환 시 임시 개체가 생성될 수 있다.

double x = 1.23;
int y = static_cast<int>(x);

임시 개체의 생명 주기

  1. 표현식의 끝 : 임시 개체는 표현식이 끝날 때 파괴된다.

  1. 참조 연장 : 'const' 참조로 바인딩 된 경우, 참조의 생명 주기 동안 임시 개체의 수명이 연장된다.

  1. 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