8
void Animation::playAnimation() const
{
    static const int index = 0;
    const std::string& animationFileName = 
    m_animationContainer.getAnimationName(index);
    static const int zOrder = -1;
    static bool isLooping = false;

    AnimationBank::play(animationFileName,
                        zOrder,
                        isLooping);
}

Is there any benefit to to define constant local variables as static? Or it is unnecessary and even bad practice.

9

Beyond @Christophe's very good answer, the code generated for the static is most likely worst than for the local variable, so if you're interested the under-the-hood benefit, the statics are worse on modern processors.

The reason is that the statics must be located somewhere in memory that can be found by all the other threads and by all the other invocations. This basically means putting them in global memory.

Over the years, processors & compilers together have significantly optimized access to local variables due to the popularity of their usage, as compared with other variables, such as globals, statics, and fields. The compiler may choose to store a local variable in a CPU register, and even if it doesn't (so it uses the invocation stack instead) all of the stack is almost certainly in the cache. Accessing the stack is usually a short displacement addressing mode (off the stack pointer register). However, accessing globals or statics usually requires and extended offset or absolute address, so the resulting instructions doing so are longer than their equivalent for stack memory access.

All that being said, however, due to the combination of static and const the compiler may detect that it can substitute the constant value at the point of usage, so perhaps use of const mitigates the above. Still, your snippet shows at least one non-const statics, so perhaps the discussion is topical.

  • 4
    Are you sure static constants have to be put into memory? – MikeMB Jun 23 '17 at 20:34
5

It is not a question of benefits, but a question of semantics:

  • A static variable in a function (even a member function), means that the variable is shared between all the calls of that function. So one call of that function has a side effect on the subsequent calls.

  • A non static variable is unique to each execution of the function.

So, unless it is required for some specific and well justified reason, keep local variables non static.

Additional remark: The static variable is also shared accross different threads. So calling this function from more than one thread at a time might result in race conditions and UB (even if called for different objects).

  • 4
    Starting from C++11, the standard defines const static variables thread safe. Non-const, static variables on the other hand, are not. – Teimpz Jun 9 '17 at 21:34
  • 3
    This is about constants. They can't change their value, so there is no meaningful semantical difference between constants that are shared between multiple function calls and local ones. – MikeMB Jun 23 '17 at 20:31
  • The only difference is if the initialization has side effects. – MikeMB Jun 23 '17 at 20:33
  • 1
    @MikeMB Indeed, my answer was general. If it's a const, the optimizer will propagate it anyway, whether it's static or not. But there's still a subtle difference: as you pointed out, the object initializer could use some side effets, so that choosing static or not could distort the expected behavior. For all these reasons, I'd still strongly suggest to use static if and only if the const is really something that is intrinsically linked to the class. Show the intent in the code and let the optimizer do its job. – Christophe Jun 23 '17 at 21:12
0

A local variable is initialized or constructed every time the function is called. Local variables are stored on the stack and therefore are generally thread safe.

A static local variable is initialized or constructed only once; the first time the function is called. Local static variables are not stored on the stack and therefore are generally not thread safe.

A const local variable is a variable that does not change and is initialized or constructed every time the function is called. Local const variables are stored on the stack and therefore are generally thread safe.

A static const local variable is a variable that does not change and is initialized or constructed only once; the first time the function is called. Local static const variables are not stored on the stack and therefore are generally not thread safe.

Compilers may be able to optimize const variables into a compile time constant.

Compilers may be able to optimize non-static variables by by keeping them in registers rather than on the stack.

  • Why would local static const variables not be thread safe? Their value is constant even if their value is located on the hep. – unified modeling sandwich Jun 9 '17 at 6:14
  • @unifiedmodelingsandwich: What if two threads make the first call to the function at the same time? Then both threads would try to initialize that static const variable. – Bart van Ingen Schenau Jun 9 '17 at 7:01
  • Not in C++11 they wouldn't. Dynamic initialization of function-local statics is thread-safe. – Sebastian Redl Jun 9 '17 at 7:46
  • @BartvanIngenSchenau Since C++11, static local variable initialisation is thread-safe. The A is still correct in saying that it is not in general thread safe, but it would be more accurate to say that this is only the case prior to C++11. – unified modeling sandwich Jun 9 '17 at 7:52
  • 1
    @unifiedmodelingsandwich: Thanks for the info. I am mostly stuck on C++03 :-( – Bart van Ingen Schenau Jun 9 '17 at 8:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.