"(c++20) consteval, constinit"
C++20에 추가된 Language 중 consteval, constinit에 대해서 알아보고 기존에 있었던 const와 constexpr과 비교해보려고한다. 일단 어떤 단어의 줄임말인지 확인하고 넘어가자 ~
- const: Constant 상수
- constexpr: Constant Expression 표현// c++11
- consteval: Constant Evaluation 검증 // c++20
- constinit: Constrant Initialization 초기화 // c++20
함수에 키워트를 붙였을 때, 변수에 키워드를 붙였을 때를 나눠서 정리해보았다.
1. 함수 (일반 vs constexpr vs consteval)
먼저 선행해야 할 개념은 런타임(RunTime)과 컴파일(Compile)타임이다.
간단하게 게임이라고 가정할 때 실행프로그램이 만들어지는 과정이 오래 걸리더라도 게임을 실행 후 게임을 할 때 버벅이지 않는게 더 중요하다. 소스코드를 실행까지 하는 과정은 아래와 같다.
Build → Compile(Compile Time) → Link → 실행파일(.exe) → 실행( RunTime )
- Compile Time: 소스코드를 컴파일이라는 과정으로 실행파일을 만드는 과정
- RunTime: 컴퓨터 프로그램이 실행되고 있는 동안의 동작
우리가 만드는 함수는 아무런 키워드 없이는 "런타임"에 동작을 한다. 당연히 런타임에 계산이 되어야하는 함수가 있겠지만 "컴파일"에 계산이 되어도 상관이 없다면 "런타임"에 연산을 되도록 하지 않도록 하는것이 게임을 플레이하는데 좋다.
코드로 (일반 vs constexpr vs consteval) 사용법을 알아보자.
int RunTime(int n)
{
return n * n;
}
// c++11
// constexpr: 최대한 컴파일 타임
constexpr int RunOrCompileTime(int n)
{
return n * n;
}
// c++20
// consteval: 100% 컴파일 타임
consteval int CompileTime(int n)
{
return n * n;
}
int main(void)
{
// [1]번구간 ===================================================
int val1 = RunTime(10);//ok
int val2 = RunOrCompileTime(10);//ok
int val3 = CompileTime(10);//ok
// [2]번구간 ===================================================
enum EnumTest // <- enum은 compile Time에 확정되어야 한다.
{
VAL_1 = RunTime(10),//error
VAL_2 = RunOrCompileTime(10),//ok
VAL_3 = CompileTime(10),//ok
};
// [3]번구간 ===================================================
int a = 10; // <- Stack
int val1 = RunTime(a);// ok
constexpr int val2 = RunOrCompileTime(a); // error
int val2 = RunOrCompileTime(a);// ok
int val3 = CompileTime(a);// error
return 0;
}
(1). [1번] 구간
컴파일 타임이든 런타임이든 둘다 문제 없기 때문에 error가 발생하지 않는다.
😝Tip. 컴파일 타임에서 만들어지는지 런타임에서 만들어지는지 가장 확실하게 볼 수 있는 방법은?
디버깅을 해보는 것이다.!! 디버깅 → 창 → 디스어셈블러 로 확인해보자.
사진은 [1]번 구간 기계어 코드 인데 CompileTime함수만 64진수로 바로 mov val3 64h val3에 64h 상수를 덮어씌어라. 하고 있다. 이는 컴파일타임에 계산이 미리되어있기 때문에 위 함수 RunTime과 RunOrCompileTime처럼 임시객체를 만들고 함수를 부르는 과정을 생략하고 있는 걸 볼 수 있다.

(2). [2번] 구간
enum은 stack에 저장되며 컴파일 타임에 정해져야 한다. 즉 consteval은 error를 뱉는다.
(3). [3번] 구간
a는 변수이므로 a를 매개변수로 주어질 때 런타임 함수가 불려야 한다. 여기서 확인 할 점은 constexpr int val2 = RunOrCompileTime(a); // error
int val2 = RunOrCompileTime(a);// ok
이 둘의 차이인데 constexpr는 함수에 붙이면 최대한 컴파일 타임에 계산하겠다는 뜻이지만 변수에 붙이면 무조건 컴.파.일. 타임 상수이므로 RunOrCompileTime(a)는 런타임 계산이 되므로 상수값을 뱉을 수 없기 때문에 error를 뱉는다.
2. 변수 ( const vs constexpr vs constinit)
이제 변수에 키워드를 붙일 때 의미를 확인해보자.
// [1번]구간 const ==============================================
const int constintval = sqrRunTime(10);
constintval++; //error
// [2번]구간 constexpr ==========================================
constexpr int constExprVal = sqrCompileTime(10);
constExprVal++; //error
// [3번]구간 constinit ==========================================
constinit thread_local int constlnitVal = sqrRunOrCompileTime(10);
(1). [1번] 구간 const
- 컴파일타임/런타임 + constness(절대로 변하면 안된다. 상수성)필요하다.
- const 변수의 초기화는 런타임까지 지연시킬 수 있다.
(2). [2번] 구간 constexpr
- 컴파일타임 + constness
constexpr 함수에 붙으면 런타임 혹은 컴파일 타임 모두 되지만
constexpr 변수에 붙으면 컴.파.일 타임
(3). [3번] 구간 constinit
- 컴파일타임 + constness(x) + static/thread_local
- global 변수, static 변수, thread_local 변수를 대상으로 사용한다.
- 프로그램 시작 시 메모리 할당, 프로그램이 끝나면 메모리 해제된다.
- thread_local 변수는 thread에 종속성, 특정 thread가 해당 데이터를 사용할 때 생성된다.

바이용 ~
내용 출저: 인프런 Inflearn - Rookiss 쌤 강의인 C++20 훑어보기 중.
'👨🏻💻 programming > ◽ c, c++' 카테고리의 다른 글
(c++20) Conditional Explicit Constructor (0) | 2024.06.17 |
---|---|
(c++20) [Three-way Comparsion(3방향 비교 연산자)/우주선] 연산자 (0) | 2024.06.14 |
[c++17] 전문자를 위한 c++17 새로운 내용 북마크 (0) | 2024.03.11 |
[C++] Map의 Key로 Class/Struct 넣기 (2) | 2023.08.11 |
(c++) 인코딩(Encoding),유니코드(Unicode), 로케일, 패싯 (0) | 2022.09.07 |
안 하는 것 보다 낫겠지
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!