函数中的静态constexpr变量有意义吗? [英] Does static constexpr variable inside a function make sense?

查看:165
本文介绍了函数中的静态constexpr变量有意义吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在函数内有一个变量(例如,一个大数组),则将其声明为 static constexpr constexpr 保证在编译时创建数组,所以 static 会没有用吗?

If I have a variable inside a function (say, a large array), does it make sense to declare it both static and constexpr? constexpr guarantees that the array is created at compile time, so would the static be useless?

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

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

Is the static actually doing anything there in terms of generated code or semantics?

推荐答案

答案是,静态不仅有用,而且总是很需要的。

The short answer is that not only is static useful, it is pretty well always going to be desired.

首先,请注意静态 constexpr 是彼此完全独立的。 静态定义对象在执行期间的生存期; constexpr 指定对象在编译期间应该可用。在时间和空间上,编译和执行是不相交和不连续的。因此,一旦程序编译完毕, constexpr 就不再相关了。

First, note that static and constexpr are completely independent of each other. static defines the object's lifetime during execution; constexpr specifies that the object should be available during compilation. Compilation and execution are disjoint and discontiguous, both in time and space. So once the program is compiled, constexpr is no longer relevant.

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

Every variable declared constexpr is implicitly const but const and static are almost orthogonal (except for the interaction with static const integers.)

C ++ 对象模型(§ 1.9)要求除位域以外的所有对象至少占用一个字节的内存并具有地址;此外,在给定时刻在程序中可观察到的所有此类对象必须具有不同的地址(第6段)。这并不需要编译器为每次使用本地非静态const数组的函数调用在堆栈上创建一个新数组,因为编译器可以避开 as c $ c>原理,条件是它可以证明没有其他对象可以观察到。

The C++ object model (§1.9) requires that all objects other than bit-fields occupy at least one byte of memory and have addresses; furthermore all such objects observable in a program at a given moment must have distinct addresses (paragraph 6). This does not quite require the compiler to create a new array on the stack for every invocation of a function with a local non-static const array, because the compiler could take refuge in the as-if principle provided it can prove that no other such object can be observed.

不幸的是,除非函数很简单,否则证明起来并不容易。例如,它不会调用任何其他函数(其主体在翻译单元中不可见),因为根据定义,数组或多或少是地址。因此,在大多数情况下,每次调用时都必须在堆栈上重新创建非静态 const(expr)数组,这使我们无法在以下位置进行计算:

That's not going to be easy to prove, unfortunately, unless the function is trivial (for example, it does not call any other function whose body is not visible within the translation unit) because arrays, more or less by definition, are addresses. So in most cases, the non-static const(expr) array will have to be recreated on the stack at every invocation, which defeats the point of being able to compute it at compile time.

另一方面,所有观察者都共享一个本地 static const 对象,而且可能即使从未调用定义在其中的函数也不会被初始化。因此,以上都不适用,并且编译器不仅可以自由生成它的单个实例,还可以自由使用。可以免费在只读存储中生成单个实例。

On the other hand, a local static const object is shared by all observers, and furthermore may be initialized even if the function it is defined in is never called. So none of the above applies, and a compiler is free not only to generate only a single instance of it; it is free to generate a single instance of it in read-only storage.

因此,您绝对应该使用静态constexpr

So you should definitely use static constexpr in your example.

但是,在某些情况下,您不想使用静态constexpr 。除非 constexpr 声明的对象是使用了ODR 或声明为静态,编译器可以自由地完全不包含它。这非常有用,因为它允许使用编译时临时 constexpr 数组,而不会用不必要的字节来污染已编译的程序。在那种情况下,您显然不希望使用 static ,因为 static 可能会迫使对象存在于运行时。

However, there is one case where you wouldn't want to use static constexpr. Unless a constexpr declared object is either ODR-used or declared static, the compiler is free to not include it at all. That's pretty useful, because it allows the use of compile-time temporary constexpr arrays without polluting the compiled program with unnecessary bytes. In that case, you would clearly not want to use static, since static is likely to force the object to exist at runtime.

这篇关于函数中的静态constexpr变量有意义吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆