1. constexpr이란?
constexpr은 C++11에서 도입된 키워드로, 컴파일 타임에 상수를 만들어 준다고 한다.
const라는 키워드도 상수를 만들 수 있지만, constexpr은 변수 뿐만 아니라 함수, 클래스 생성자에도 적용이 가능하다!
또한, const 키워드는 컴파일 상수 / 런타임 상수 2가지로 작동 가능하지만 constexpr은 컴파일 상수로만 기능한다.
2. constexpr 변수
#include <iostream>
int main(){
int n = 10;
const int constN1 = 100; // OK, initialized at compile-time
const int constN2 = n; // OK, intialized at run-time
constexpr int constExprN1 = 100; // OK, initialized at compile-time
//constexpr int constExprN2 = n; // Error, initialized at run-time
return 0;
}
3. constexpr 함수
constexpr 함수는 함수의 반환 값을 컴파일 타임에 계산할 수 있다는 특징이 있다.
constexpr 함수에는 다음과 같은 규칙이 적용된다.
- constexpr 함수는 리터럴 형식만 사용하고 반환해야 한다.
- constexpr 함수는 재귀적일 수 있다.
- (C++20 이전) constexpr 함수는 가상일 수 없으며, 바깥쪽 클래스에 가상 기본 클래스가 있는 경우 생성자는 constexpr로 정의될 수 없다.
- (C++20 이상) constexpr 함수가 가상일 수 있다.
- 본문은 = default 또는 = delete로 정의할 수 있다.
- 본문에는 goto 문이나 try 블록이 포함될 수 없다.
- ...
#include <iostream>
constexpr int fact(int n){
if(n<0) return 0;
if(n==0) return 1;
return n * fact(n-1);
}
int main(){
constexpr int n = fact(5);
}
근데 함수의 반환 값이 런타임에 계산되는 것과 컴파일 타임에 계산되는 것, 둘의 차이가 어떤 것인지 궁금했다.
[모던 C++] 컴파일 상수 constexpr
constexpr이란 constexpr은 C++11부터 지원되기 시작한 컴파일 상수이다. 11부터 시작해서 23에 이르기까지 constexpr은 그 지원 범위를 점차 늘려왔고, 많은 C++ 프로그래머로부터 각광을 받았다고 한다.
nx006.tistory.com
위 블로그 내용에 따르면, 어셈블리어 코드로 확인했을 때 확연히 차이나는 것을 볼 수가 있었다.
실제 위의 코드를 https://godbolt.org/에서 확인해본 결과, 아래와 같이 차이가 났었다.
// const 키워드 사용
// CPP
#include <iostream>
const int fact(int n){
if(n<0) return 0;
if(n==0) return 1;
return n * fact(n-1);
}
int main(){
const int n = fact(5);
}
// Assembly
fact(int):
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], edi
cmp DWORD PTR [rbp-4], 0
jns .L2
mov eax, 0
jmp .L3
.L2:
cmp DWORD PTR [rbp-4], 0
jne .L4
mov eax, 1
jmp .L3
.L4:
mov eax, DWORD PTR [rbp-4]
sub eax, 1
mov edi, eax
call fact(int)
imul eax, DWORD PTR [rbp-4]
.L3:
leave
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov edi, 5
call fact(int)
mov DWORD PTR [rbp-4], eax
mov eax, 0
leave
ret
// constexpr 키워드 사용
// CPP
#include <iostream>
constexpr int fact(int n){
if(n<0) return 0;
if(n==0) return 1;
return n * fact(n-1);
}
int main(){
constexpr int n = fact(5);
}
// Assembly
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 120
mov eax, 0
pop rbp
ret
단순히 확인해봐도 큰 차이가 보인다.
컴파일 시간이 오래 걸린다는 단점이 있지만, 런타임에 계산하는 것보다는 훨 나아보이는 방식이다.
결과 값이 수시로 바뀌는 경우가 아니라면 constexpr를 사용하는 것이 성능 상의 큰 도움이 될 것 같다.
References
https://en.cppreference.com/w/cpp/language/constexpr
constexpr specifier (since C++11) - cppreference.com
[edit] Explanation The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time. Such variables and functions can then be used where only compile time constant expressions are allowed (provided that
en.cppreference.com
https://learn.microsoft.com/en-us/cpp/cpp/constexpr-cpp?view=msvc-170
constexpr (C++)
Guide to the C++ language constexpr keyword.
learn.microsoft.com
'언어 > C,C++' 카테고리의 다른 글
[Win32] Visual Studio Win32 LNK2019 오류 해결 (0) | 2023.12.28 |
---|---|
C language Chapter 7. 배열 (0) | 2022.10.09 |
C Language Chapter 6. 반복문 (0) | 2020.08.03 |
C language Chapter 5. C언어의 조건문(+switch문) (0) | 2020.04.17 |
C language Chapter 4. C언어의 입출력 (0) | 2020.03.17 |