constinit
是P1143中提出的C ++ 20中的新关键字和说明符。
标准中提供了以下示例:
const char * g() { return "dynamic initialization"; }
constexpr const char * f(bool p) { return p ? "constant initializer" : g(); }
constinit const char * c = f(true); // OK
constinit const char * d = f(false); // ill-formed
我想到了几个问题:
什么constinit
意思 为什么要引入?在什么情况下我们应该使用它?
它使变量不可变吗?是暗示const
还是constexpr
?
变量可以是const
和constinit
吗?怎么样constexpr
和constinit
?
可以将说明符应用于哪些变量?为什么我们不能将其应用于static
非thread_local
变量?
有性能优势吗?
该问题旨在作为constinit
一般性后续问题的参考。
- 什么
constinit
意思 为什么要引入?在什么情况下我们应该使用它?
使用静态存储持续时间初始化变量可能会导致两个结果¹:
变量在编译时初始化(constant-initialization);
变量在控件第一次通过其声明时进行初始化。
情况(2)有问题,因为它可能导致静态初始化顺序fiasco,这是与全局对象相关的危险错误的来源。
该constinit
关键字只能与变量可应用于静态存储时间。如果修饰后的变量在编译时未初始化,则程序格式错误(即不编译)。
使用constinit
确保变量在编译时被初始化,并且静态初始化顺序惨败不会发生。
- 它使变量不可变吗?是暗示
const
还是constexpr
?
不,不。
但是,constexpr
确实暗示constinit
。
- 变量可以是
const
和constinit
吗?怎么样constexpr
和constinit
?
可以同时是const
和constinit
。不能同时是constexpr
和constinit
。从措辞:
在一个最
constexpr
,consteval
和constinit
关键字应该出现在DECL说明符-SEQ。
constexpr
不等同于const constinit
,因为前者要求不断销毁,而后者则不要求持续销毁。
- 可以将说明符应用于哪些变量?为什么我们不能将其应用于
static
非thread_local
变量?
它只能应用于具有静态或线程存储持续时间的变量。将其应用于其他变量是没有意义的,因为constinit
与静态初始化有关。
- 有性能优势吗?
不能。但是,在编译时初始化变量的附带好处是,它不需要在程序执行期间进行初始化的指令。constinit
帮助开发人员确保确实如此,而不必猜测或检查生成的程序集。
¹:参见https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句