you are an embedded programmer doing f.ex. state machine
implementations in C: please, don't use variables declared as
Once I came across code containing static variables. Surprise! It wasn't one variable, there were hundreds. I will describe why this turned out to be a problem. Even if they were there by design, not coincidence. They had represented no problem on initial usage.
Firstly, the variable (or function) has file scope only. This means that it is not possible to export any knowledge about this static object outside the file. This is nice. Also, it defines the name space of the object. So, the name may be reused (check this).
Secondly, the static keyword, for variables, means that they may be statically allocated in RAM memory. Once given an address, that address is kept, at all times.
The stack is not involved in any way with statics. The stack contains the parameters to and local variables in functions. It expands on calls and shrinks on returns. Locations are reused. It may not be so easy to see the different semantic of storage qualifiers. You could look in a function and see two local variables, one with the static keyword and one without. The one with static is at the init address space; the one without is on the stack.
Which variable will live the longest: the local static
or the local stack-based non-static? As the name suggests, the static
variable survives at all times. So, if you assign an initialization value (
A static variable of this sort certainly does not give the programmer much overview of what's happening (if this is needed). However, you were only assumed to use what the other guy programmed, and should not care that it contains loads of statics. But, should you indeed need to understand, then there would have been an alternative solution. I'll come to that shortly.
Use of hidden statics certainly works for applications
running in big operating systems, like Mac OS X or Windows. These
operating systems are able to load a binary file. This means that every
address allocation is local. So, if you have a static in a program
called TuringMachine, the operating system could assign that static to
the storage address 0x100000 (0x=hex). If you start TuringMachine a
second time, the operating system could assign the same named static
into address 0x2000000. The operating system gives each instance of the
program an individual section of its heap with a
call to the operating system's
Observe that when a function contains local static variables, it's not necessary with many parameters to functions. They keep their own state in permanent storage. This is reminescent of one of the traits of object-oriented programming or process-oriented programming. It's good.
However, an object built with static is like a house on a hundred poles - it's hard to lift from the ground. Should one want to create a one new instance of this sort of object - that's when the problems start. Create two variables of each, two functions of each, all suffixed my "_1" and "_2"? Complex, not much scalable and reluctant to errors.
Instead, make a single struct containing all variables, have some callee on the outside malloc the data space for it, or do it inside an init function. Then, parameterize all functions with a pointer to this single struct. This is much more portable.
However, there is a price. This dynamic memory
incurs an extra indirection every time a variable inside the struct
needs to be accessed (the
But, if there is a chance your internal object is going
to be so popular that somebody may want it, do consider the malloc'ed
solution. And should it later be used inside a small real-time
operating system that does not have loading of binary files or objects
(where all has to be statically linked into a single burn before the
op-sys starts), then absolutely
consider dynamic memory handling. In most small embedded systems you
would only need to malloc, and never
So, every time you use static, learn to see the blinking yellow light.
(Updated 31 March '09)
Other publications at http://www.teigfam.net/oyvind/pub/pub.html