静态constexprvariables是否有意义?
如果我有一个函数内的variables(比如说一个大数组),声明它是static
还是constexpr
有意义的? constexpr
保证数组是在编译时创build的,那么static
是无用的吗?
void f() { static constexpr int x [] = { // a few thousand elements }; // do something with the array }
static
实际上是根据生成的代码还是语义来做任何事情?
简单的答案是,不仅是static
有用的,它总是相当不错的。
首先要注意的是, static
和constexpr
是完全独立的。 static
定义执行期间的对象的生命周期; constexpr
指定对象在编译期间应该可用。 编译和执行在时间和空间上是不相交和不连贯的。 所以一旦程序被编译, constexpr
就不再相关了。
每个声明constexpr
variables都是隐式的const
但const
和static
几乎是正交的(除了与static const
整数的交互)。
C++
对象模型(§1.9)要求比特字段以外的所有对象至less占用一个字节的内存并具有地址; 而且在一个特定时刻,在一个节目中观察到的所有这些对象都必须有不同的地址(第6段)。 这并不需要编译器在每次调用具有本地非静态const数组的函数时在堆栈上创build一个新数组,因为编译器可以采用as-if
原则避难,前提是它可以certificate没有其他类似的对象可以被观察到。
不幸的是,除非函数是微不足道的(例如,它不调用任何其他函数的主体在翻译单元中不可见),否则不容易certificate,因为根据定义,或多或less的数组是地址。 所以在大多数情况下,非静态const(expr)
数组在每次调用时都必须在堆栈上重新创build,这在编译时就无法计算。
另一方面,一个局部static const
对象被所有的观察者共享,而且即使被定义的函数永远不会被调用,它也可以被初始化。 所以以上都不适用,编译器不仅仅是自由生成一个实例, 可以在只读存储器中自由生成一个实例。
所以你应该在你的例子中使用static constexpr
。
但是,有一种情况你不想使用static constexper
。 除非一个constexpr
声明的对象是ODR使用的或声明为static
,编译器可以根本不包含它。 这非常有用,因为它允许使用编译时临时constexpr
数组,而不会用不必要的字节污染已编译的程序。 在这种情况下,你显然不想使用static
,因为static
可能迫使对象在运行时存在。