Namespaces
Variants

constinit specifier (since C++20)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

목차

설명

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

키워드

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으로 설정함