[C++] const와 constexpr : 상수 선언의 차이

[C++] const와 constexpr : 상수 선언의 차이

개요

안녕하세요. 이번 글에서는 C++의 const와 C++11에서 추가된 constexpr에 대해 알아보겠습니다. 둘 다 “바꾸지 않는 값”을 다루지만, const는 “바꾸지 않겠다는 약속”이고 constexpr는 “컴파일 시점에 값이 정해진다”는 점에서 다릅니다. 이 차이를 중심으로 정리하겠습니다.

const — 바꾸지 않겠다는 약속

const가 붙은 변수는 초기화 후 값을 바꿀 수 없습니다. 값이 실행 중에 정해져도 상관없고, “이 값은 변경하지 않는다”는 것만 보장합니다.

const int a = 10;
// a = 20;          // 에러: const는 변경 불가

int x = getValue();  // 실행 중에 정해지는 값이어도
const int b = x;     // const로 받을 수 있음 (값 고정)

즉 const는 값이 언제 정해지든 상관없이, 그 뒤로 바꾸지 못하게 막는 것이 핵심입니다.

constexpr — 컴파일 시점 상수

constexpr는 한 걸음 더 나아가, 그 값이 컴파일 시점에 계산되어 결정되도록 강제합니다. 그래서 배열 크기처럼 “반드시 컴파일 때 알아야 하는 자리”에 쓸 수 있습니다.

constexpr int size = 10;     // 컴파일 시점에 10으로 확정
int arr[size];               // OK: 배열 크기로 사용 가능

int n = getValue();          // 실행 중에 정해지는 값
// constexpr int m = n;      // 에러: 컴파일 시점 값이 아님
const int k = n;             // 이건 OK (const는 가능)

constexpr에는 반드시 컴파일 시점에 알 수 있는 값만 올 수 있습니다. 실행 중에 정해지는 값은 const로는 받을 수 있어도 constexpr로는 받을 수 없습니다.

const vs constexpr

구분constconstexpr
의미값을 바꾸지 않음컴파일 시점에 값이 확정됨
값이 정해지는 때실행 중이어도 됨반드시 컴파일 시점
배열 크기 등에 사용불가(실행 중 값이면)가능
도입C++98C++11

정리하면 모든 constexpr는 const이지만, 모든 const가 constexpr인 것은 아닙니다. 컴파일 시점 상수가 꼭 필요하면 constexpr, 단순히 변경만 막으면 const입니다.

constexpr 함수

constexpr는 함수에도 붙일 수 있습니다. 그러면 인자가 컴파일 시점에 정해질 때 함수 결과도 컴파일 시점에 계산됩니다. 실행 중 값이 들어오면 일반 함수처럼 동작합니다.

constexpr int square(int x)
{
    return x * x;
}

int arr[square(5)];   // 컴파일 시점 계산 → 크기 25 배열
int n = getValue();
int y = square(n);    // 실행 중 값 → 일반 함수처럼 동작

정리

  • const: 초기화 후 값을 바꾸지 않겠다는 약속 (값은 실행 중에 정해져도 됨).
  • constexpr: 값이 컴파일 시점에 확정됨 → 배열 크기 등 상수식이 필요한 자리에 사용 가능.
  • 모든 constexpr는 const지만, 반대는 성립하지 않는다.
  • constexpr 함수는 인자가 컴파일 시점 값이면 결과도 컴파일 시점에 계산된다.

단순히 변경을 막으려면 const, 컴파일 시점에 값이 확정되어야 하면 constexpr를 쓴다고 기억하면 됩니다. 이상으로 const와 constexpr에 대해 간단히 알아보았습니다.

참고