静态constexprvariables是否有意义?

如果我有一个函数内的variables(比如说一个大数组),声明它是static还是constexpr有意义的? constexpr保证数组是在编译时创build的,那么static是无用的吗?

 void f() { static constexpr int x [] = { // a few thousand elements }; // do something with the array } 

static实际上是根据生成的代码还是语义来做任何事情?

简单的答案是,不仅是static有用的,它总是相当不错的。

首先要注意的是, staticconstexpr是完全独立的。 static定义执行期间的对象的生命周期; constexpr指定对象在编译期间应该可用。 编译和执行在时间和空间上是不相交和不连贯的。 所以一旦程序被编译, constexpr就不再相关了。

每个声明constexprvariables都是隐式的constconststatic几乎是正交的(除了与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可能迫使对象在运行时存在。