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.
-
1see What is the problem with "Pros and Cons"?gnat– gnat2017年06月08日 19:14:55 +00:00Commented Jun 8, 2017 at 19:14
-
2...also, please don't cross-post : stackoverflow.com/questions/44431574/… "Cross-posting is frowned upon as it leads to fragmented answers splattered all over the network..."gnat– gnat2017年06月08日 19:15:48 +00:00Commented Jun 8, 2017 at 19:15
3 Answers 3
Beyond @Christophe's very good answer, the code generated for the static is most likely worse than the one for the local variable, so if you're interested the under-the-hood benefit, 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, 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.
-
7Are you sure static constants have to be put into memory?MikeMB– MikeMB2017年06月23日 20:34:28 +00:00Commented Jun 23, 2017 at 20:34
-
@MikeMB yes, they have, as the CPU needs to retrieve their value from somewhere. The difference is where: it can be in the .text segment, or others. IIUC it's up to the compiler decide, even if again IIUC the consensus about it is to use .text, as it is global and read onlyAlessandro Bertulli– Alessandro Bertulli2025年05月22日 11:21:18 +00:00Commented May 22 at 11:21
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).
-
4Starting from C++11, the standard defines const static variables thread safe. Non-const, static variables on the other hand, are not.Teimpz– Teimpz2017年06月09日 21:34:38 +00:00Commented Jun 9, 2017 at 21:34
-
8This 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– MikeMB2017年06月23日 20:31:56 +00:00Commented Jun 23, 2017 at 20:31
-
The only difference is if the initialization has side effects.MikeMB– MikeMB2017年06月23日 20:33:11 +00:00Commented Jun 23, 2017 at 20:33
-
1@MikeMB Indeed, my answer was general. If it's a
const
, the optimizer will propagate it anyway, whether it'sstatic
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 usestatic
if and only if theconst
is really something that is intrinsically linked to the class. Show the intent in the code and let the optimizer do its job.Christophe– Christophe2017年06月23日 21:12:29 +00:00Commented Jun 23, 2017 at 21:12 -
So semantically, it doesn't make a difference if the variable is a constant and its address is not taken. The rest of the question is: which one should you use?Stack Exchange Broke The Law– Stack Exchange Broke The Law2019年11月22日 13:54:20 +00:00Commented Nov 22, 2019 at 13:54
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.
-
1Why 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– unified modeling sandwich2017年06月09日 06:14:58 +00:00Commented Jun 9, 2017 at 6:14 -
1@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– Bart van Ingen Schenau2017年06月09日 07:01:09 +00:00Commented Jun 9, 2017 at 7:01 -
1Not in C++11 they wouldn't. Dynamic initialization of function-local statics is thread-safe.Sebastian Redl– Sebastian Redl2017年06月09日 07:46:23 +00:00Commented Jun 9, 2017 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– unified modeling sandwich2017年06月09日 07:52:30 +00:00Commented Jun 9, 2017 at 7:52
-
1@unifiedmodelingsandwich: Thanks for the info. I am mostly stuck on C++03 :-(Bart van Ingen Schenau– Bart van Ingen Schenau2017年06月09日 08:09:20 +00:00Commented Jun 9, 2017 at 8:09