constinit 说明符 (C++20 起)

来自cppreference.com
< cpp‎ | language

解释

constinit 说明符声明拥有静态或线程存储期的变量。如果变量以 constinit 声明,那么它的初始化声明必须应用 constinit。如果以 constinit 声明的变量拥有动态初始化(即使作为静态初始化执行),那么程序非良构。如果在初始化声明点没有可达的 constinit 声明,那么程序非良构,不需要诊断。

constinit 不能和 constexprconsteval 一同使用。声明的变量为引用时, constinit 等价于 constexpr。声明的变量为对象时, constexpr 强制对象必须拥有静态初始化和常量析构,并使对象有 const 限定,然而 constinit 不强制常量析构和 const 限定。结果是拥有 constexpr 构造函数且但没有 constexpr 析构函数的类型(例如 std::shared_ptr<T>)的对象可能可以用 constinit,但不能用 constexpr 声明。

const char* g() { return "动态初始化"; }
constexpr const char* f(bool p) { return p ? "常量初始化器" : g(); }
 
constinit const char* c = f(true);     // OK
// constinit const char* d = f(false); // 错误

constinit 也能用于非初始化声明,以告知编译器 thread_local 变量已被初始化,以减少隐藏的防卫变量所致的开销

extern thread_local constinit int x;
int f() { return x; } // 无需检查防卫变量

关键词

constinit

示例

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
LWG 2543 C++20 声明为 constinit 的变量以静态初始化的一部分被动态初始化时的行为不明确 此时程序非良构

参阅

consteval 说明符(C++20) 指定函数为立即函数,即对该函数的每次调用必须在常量求值中
constexpr 说明符(C++11) 指定变量或函数的值能在编译时计算
常量表达式 定义可以在编译器求值的表达式
常量初始化 静态变量的初始值设为编译期常量
零初始化 将对象的初始值设为零