c – 静态constexpr变量有意义吗?

如果我在一个函数内部有一个变量(比如一个大数组),它是否有意义的声明它静态和constexpr? constexpr保证数组在编译时创建,所以静态是无用的?

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

静态实际上在生成的代码或语义方面做什么?

简短的回答是,不仅静态有用,它是很好总是需要的。

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

每个变量声明的constexpr是隐式的const,但const和static几乎是正交的(除了与静态const整数的交互)。

C对象模型(§1.9)要求除位字段之外的所有对象占用至少一个字节的存储器并具有地址;此外,在给定时刻在程序中可观察到的所有这些对象必须具有不同的地址(第6段)。这并不需要编译器在每次调用具有局部非静态const数组的函数时在堆栈上创建一个新的数组,因为编译器可以在as-if原则中避开,只要它能证明没有其他的对象可以观察。

这不容易证明,不幸的是,除非函数是微不足道的(例如,它不调用任何其他函数的主体在翻译单元内是不可见的),因为数组,或多或少的定义是地址。因此,在大多数情况下,非静态const(expr)数组必须在每次调用时在堆栈上重新创建,这会破坏能够在编译时计算它的点。

另一方面,局部静态const对象被所有观察者共享,并且此外可以被初始化,即使其中定义的函数从未被调用。所以上面没有一个适用,并且编译器自由不仅仅生成它的一个实例;它可以在只读存储器中自由生成它的一个实例。

所以你应该肯定使用静态constexpr在你的例子。

但是,有一种情况,你不想使用静态constexper。除非一个constexpr声明的对象是ODR使用或声明的静态,编译器可以不包括它。这是非常有用的,因为它允许使用编译时临时constexpr数组,而不会以不必要的字节污染编译程序。在这种情况下,你显然不想使用静态,因为静态可能会迫使对象在运行时存在。

http://stackoverflow.com/questions/13865842/does-static-constexpr-variable-make-sense

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c – 静态constexpr变量有意义吗?