개요
안녕하세요. 이번 글에서는 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
| 구분 | const | constexpr |
|---|---|---|
| 의미 | 값을 바꾸지 않음 | 컴파일 시점에 값이 확정됨 |
| 값이 정해지는 때 | 실행 중이어도 됨 | 반드시 컴파일 시점 |
| 배열 크기 등에 사용 | 불가(실행 중 값이면) | 가능 |
| 도입 | C++98 | C++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에 대해 간단히 알아보았습니다.