constinit
specifier
(since C++20)
-
-
constinit- 변수가 정적 초기화, 즉 zero initialization 과 constant initialization 을 가짐을 단언합니다. 그렇지 않을 경우 프로그램은 ill-formed입니다.
-
목차 |
설명
constinit 지정자는 정적 또는 스레드 저장 기간 을 가진 변수를 선언합니다.
|
constinit 지정자는 구조化 바인딩 선언에도 적용될 수 있습니다. 이 경우, constinit 은 선언에 의해 도입된 고유 이름 변수 에도 적용됩니다. |
(C++26부터) |
변수가 constinit 로 선언된 경우, 해당 변수의 초기화 선언 에는 반드시 constinit 가 적용되어야 합니다. constinit 로 선언된 변수가 동적 초기화 를 가지는 경우( 정적 초기화로 수행되는 경우 조차도), 프로그램은 형식 오류를 갖습니다.
만약 초기화 선언 지점에서 도달 가능한 constinit 선언이 존재하지 않는다면, 프로그램의 형식이 잘못되었으며 진단이 필요하지 않습니다.
constinit 는 constexpr 와 함께 사용할 수 없습니다. 선언된 변수가 참조형일 경우, constinit 는 constexpr 와 동등합니다. 선언된 변수가 객체일 경우, constexpr 는 객체가 정적 초기화와 상수 소멸을 가져야 하며 객체를 const 한정으로 만듭니다. 그러나 constinit 는 상수 소멸과 const 한정을 요구하지 않습니다. 결과적으로 constexpr 생성자를 가지고 constexpr 소멸자가 없는 타입의 객체(예: std:: shared_ptr < T > )는 constinit 로 선언될 수 있지만 constexpr 로는 선언될 수 없습니다.
const char* g() { return "dynamic initialization"; } constexpr const char* f(bool p) { return p ? "constant initializer" : g(); } constinit const char* c = f(true); // 정상 // constinit const char* d = f(false); // 오류
constinit 는 초기화하지 않는 선언에서도 사용될 수 있으며, thread_local 변수가 이미 초기화되었음을 컴파일러에 알려서 숨겨진 가드 변수로 인해 발생하는 오버헤드를 줄일 수 있습니다.
extern thread_local constinit int x; int f() { return x; } // 가드 변수 확인이 필요 없음
참고 사항
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_constinit
|
201907L
|
(C++20) | constinit |
키워드
예제
#include <cassert> constexpr int square(int i) { return i * i; } int twice(int i) { return i + i; } constinit int sq = square(2); // OK: 컴파일 타임에 초기화 수행됨 // constinit int x_x = twice(2); // 오류: 컴파일 타임 초기화가 필요함 int square_4_gen() { static constinit int pow = square(4); // constinit int prev = pow; // 오류: constinit은 정적 또는 스레드 저장 기간을 가진 // 변수에만 적용 가능 int prev = pow; pow = pow * pow; return prev; } int main() { assert(sq == 4); sq = twice(1); // constexpr과 달리 이 값은 런타임에 나중에 변경 가능 assert(sq == 2); assert(square_4_gen() == 16); assert(square_4_gen() == 256); assert(square_4_gen() == 65536); }
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 2543 | C++20 |
constinit
로 선언된 변수가 정적 초기화의 일부로
동적으로 초기화되는 경우의 동작이 불명확했음 |
이 경우 프로그램은
형식에 맞지 않음 |
참고 항목
consteval
지정자
(C++20)
|
함수가 즉시 실행 함수 임을 지정하며, 함수에 대한 모든 호출이 상수 평가에서 이루어져야 함 |
constexpr
지정자
(C++11)
|
변수나 함수의 값을 컴파일 타임에 계산할 수 있음을 지정함 |
| 상수 표현식 | 컴파일 타임에 평가될 수 있는 표현식 을 정의함 |
| 상수 초기화 | 정적 변수들의 초기 값을 컴파일 타임 상수로 설정함 |
| 영 초기화 | 객체의 초기 값을 0으로 설정함 |