프로그래밍/C++

C++ | 02.11 Runtime vs Compile time constants

ma_heroine 2020. 5. 12. 18:55

<목차>

1. Runtime constants

2. Compile time constants

3. constexpr

 

 

Runtime vs compile time constants

상수에는 literal constants와 symbolic constants로 두가지 종류가 나뉘어져 있습니다.

literal constants은 코드에 직접적으로 삽입된 값을 말하며, symbolic constants는 변하지 않는 고정된 값을 나타냅니다.

하지만, 상수(constants)를 사실상 Runtime constants와 compile time constants로 나뉠 수 있습니다. 

 

Runtime Compile time은 각각 다른 단계의 소프트웨어 개발을 가르키는 프로그래밍 용어입니다.

Compile time은 우리가 입력한 코드가 실행 파일(exe)로 변환되는 인스턴스(instance) 단계인 반면, Runtime은 실행 파일이 실행 중인 인스턴스 단계입니다. RuntimeCompile time이라는 용어는 프로그래머들이 오류가 나타날 때, 어디서 나타나는지 이야기하기 위해 종종 사용됩니다. 


Runtime constants

Runtime constants은 프로그램이 실행중일 때(at runtime)만 초기화 값을 확인할 수 있는 상수입니다. 

컴파일러는 컴파일 시간(at compile time)에 초기 값을 결정할 수 없기 때문에 아래의 코드블럭에 있는 usersAge and myValue와 같은 변수는 모두 runtime constants입니다. 

usersAge는 사용자의 입력(오직 runtime에만 부여할 수 있음)에 의존하며 myValue는 함수에 전달된 값(runtime에만 알려져 있음)에 따라 달라집니다. 

하지만, 한번 초기화가 되면, 이러한 상수 값은 변경될 수 없습니다. 

 

- 다른 변수로 초기화 되는 const 변수

std::cout << "Enter your age: ";
int age;
std::cin >> age;
 
const int usersAge { age }; // usersAge can not be changed

 

- 함수의 파라미터로 사용되는 const 변수

void printInteger(const int myValue)
{
    std::cout << myValue;
}

 

Runtime constants 사용 예시

#include <iostream>

using namespace std;

int main()
{
    int number;
    cin >> number;

    const int special_number(number);
    
    cout << special_number << endl;
 
    return 0;
    
}

- runtime에서 상수가 결정되는 것을 runtime constants라고 합니다.


Compile time constants

Compile-time constants은 컴파일 시간(at compile-time)에 초기화 값을 확인할 수 있는 상수를 말합니다. 

위에서 중력 변수는 Compile-time constants의 예입니다. 

Compile-time constants를 통해 컴파일러가 runtime constants에는 할 수 없는 최적화(optimizations)를 수행할 수 있습니다. 

예를 들어, 중력 'gravity'이 사용될 때마다 컴파일러는 중력 'gravity'를 literal double값으로서 9.8로 간단히 대체할 수 있습니다. 

const double gravity { 9.8 };
gravity = 9.9; // not allowed, this will cause a compile error

 

Compile time constants 사용 예시

#include <iostream>

using namespace std;
 
int main()
{
    const int my_const1(123);
    
    constexpr int my_const2(123); 
    
    return 0;
}

- 컴파일(compile)할 때 이미 결정이 되는 상수를 Compile time constants라고 합니다.

- const가 runtime constants인지 compile-time constants인지의 차이를 알기위해 constexpr 키워드를 사용합니다.

- constexpr 키워드는 compile-time constants임을 보장해줍니다. 

- runtime constants 사용 예시의 코드블럭에서 special_number에는 constexpr 키워드를 붙여 줄 수 없습니다. 


const 변수를 선언할 때마다, 컴파일러는 암시적으로 runtime or compile-time constant인지 추적합니다.

 

대부분의 경우에는 이러한 추적이 문제가 되지 않지만, C++이 runtime constant대신 compile-time constant 상수를 필요로 하는 몇가지 이상한 경우가 있습니다. 

예를 들어, instantiation of type 경우에 일어나는데 이는 후에 포스팅하도록 하겠습니다. (๑و•̀Δ•́)و 

 

 

constexpr

위에서 언급했듯이, 더 많은 구체성을 제공하기 위해, C++은 constexpr 키워드를 도입했습니다.

이는 상수(constants)가 컴파일 시간 상수(compile-time constant)되도록 보장합니다.

constexpr double gravity { 9.8 }; // ok, the value of 9.8 can be resolved at compile-time
constexpr int sum { 4 + 5 }; // ok, the value of 4 + 5 can be resolved at compile-time
 
std::cout << "Enter your age: ";
int age;
std::cin >> age;
constexpr int myAge { age }; // not okay, age can not be resolved at compile-time

- constexpr 변수는 const입니다.

- constexpr을 쓰지 않아도 되지만, 구체성을 부여하기 위해 사용됨으로 const라고 합니다. 

이는 후의 다른 포스팅에서 const에 대한 영향에 대해 중요하게 다룰 예정입니다.  •̀.̫•́✧ 

 

정리 

초기화 후에 수정할 수 없고 컴파일 시간(at compile-time)에 initializer(초기화자)를 알 수 있는 변수는 constexpr로 선언해야 합니다. 

 

 

 

 

 

 

 

 

* 해당 글은 홍정모님의 따라 배우는 C++과 learcpp를 공부한 토대로 작성되었습니다. 

* 코드블러은 learncpp와 홍정모님의 강의들 듣고 정리한 것입니다.