patterncppCritical
Does static constexpr variable inside a function make sense?
Viewed 0 times
functionconstexprdoessensevariablestaticinsidemake
Problem
If I have a variable inside a function (say, a large array), does it make sense to declare it both
Is the
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
}Is the
static actually doing anything there in terms of generated code or semantics?Solution
The short answer is that not only is
First, note that
Every variable declared
The
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
On the other hand, a local
So you should definitely use
However, there is one case where you wouldn't want to use
static useful, it is pretty well always going to be desired.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.Every variable declared
constexpr is implicitly const but const and static are almost orthogonal (except for the interaction with static const integers.)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.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.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.So you should definitely use
static constexpr in your example.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.Context
Stack Overflow Q#13865842, score: 377
Revisions (0)
No revisions yet.