This question and discussion are targeted for C/C++ programmers
with five or more years of meaningful programming experience.
What
is the difference between static and local variables including
how they are initialized and used?
What to look for in your candidate's response:
This seemingly "simple" question can lead to an excellent discussion
that will show if the developer has enough experience to understand
the important depths of scope and linkage issues
in C/C++. An experienced developer will understand all of these
issues. Even a developer with a few years of experience should
begin to have broached these topics and taken an interest in
mastering them.
The way I like to kick off this question is to first ask what
a local (automatic) variable is.
Automatic (or "local") variables, if not explicitly
initialized at the point where they are defined, are unitialized
and do not retain their values when they go out of scope (leave
the block or function they were defined in). That is, local
variables are temporarily stored in an implementation-specific
location (a "stack", machine registers) whose contents likely
will be destroyed when the function or block in which they are
defined is no longer active. A good springboard question to
ask is "If you had a local variable inside a function or block
and you needed to retain it's value when it left and re-entered
the function/block, how would you do that and still keep it
in the scope of the function or block it is defined in?" The
correct answer is to say they would use the static keyword,
which allows it to retain its value as it goes in and out of
function scope. They should not be thinking that static is only
useful at file scope (outside all blocks and functions), something
an inexperienced programmer might think. Static variables occupy
storage for the life of the program.
That's a good
segue into asking them how a static variable can be initialized
and what happens to the initialization each time the statement
is reached. The answer is that it is only initialized once,
at program startup (if at file scope) or the first time it
is encountered (if inside a block or function). Local variables
with initializers, on the other hand, are initialized every
time the statement is reached.
Finally, you might
ask what is the initial value of a static variable defined
without an initializer? Is it indeterminate or is it zero?
The correct answer is 0. This should not be implementation
dependent as the ANSI C standard guarantees all uninitialized
static variables will be initialized to 0 at program startup.
If they've gotten all that correct, you know they understand
and have used the static keyword, an essential piece
of knowledge for a reasonably experienced C/C++ developer
to have. You can optionally ask them how and for what they've
used static variables. One answer is it would be used as an
"ever-done-something" state variable (for example, a boolean)
that is done once in the lifetime of the program:
static bool
bNeedRunTimeInit = true;
if(bNeedRunTimeInit)
{
bNeedRunTimeInit = false;
. do initializations here, once
}
Or it might be
used as a counter hidden or encapsulated inside a function
as opposed to using a global variable. Encapsulation or data
hiding is also a good segue into discussing how the static
keyword is used inside classes (a topic for a future newsletter).
You can stretch
them a bit and ask them what's wrong with this file (or function)
scope static initialization in C++:
static int
foo = atoi("4");
Look for an
incorrect answer that static variables, anywhere, cannot
be initialized with function calls, just other constants.
That's true for C, but nor for C++. So if they reply there
is nothing wrong with it, ask them if it's legal in C. An
advanced C++ programmer coming from a C background should
know this but this is fairly subtle and not important if they
didn't know the correct answer.
Finally, if they
get everything right, they should be able to apply their knowledge
to solving the following problem. Given the code snippet:
int sum = 0;
int k;
for (int k =1; k<=2; k++)
{
static int
xxx = 10;
{ static int xxx = 4;
sum = sum + xxx;
xxx = xxx + 2;
}
sum = sum + xxx;
xxx = xxx + 10;
}
cout << sum << endl; // what is the value of sum???
What would be the
correct value of sum when it is printed on exit of the for
loop? The correct answer is 40.
If you're looking
for an experienced developer who takes the C/C++ language
seriously, related areas of discussion would include a discuss
of global variables (variables with "external" linkage) and
asking what if they are defined several times in several files
with the same initial value? With different values? This is
a springboard to true understanding of the nuances of ANSI
C and the so-called "common model". Some implementations allow
multiple definitions: they take the first one encountered
and perhaps give warnings about the others. Other linkers
only permit at most one initializer or perhaps multiple initializers
provided they are initializing to the same value. Knowing
the range of possibilities shows experience with multiple
compilers/linkers and encountering and understanding the issues
when multiply defined external storage classes (global or
"common" variables) are used (or abused in this case -- care
should really be taken to avoid multiple definitions of the
same global variable).
Summary: understanding
the difference between file scope and function scope, local
variables, static variables and how they are stored and initialized
is a must piece of knowledge for an effective programmer who
has gone beyond the "basics" of programming and shown an interest
in becoming a better and more knowledgeable programmer.
About the author
Harry Stein received his B.S. in Mathematics and Computer
Science from the University of Pittsburgh where he began his
software development career at the Learning Research and Development
Center. Between 1979 and 1992 Harry worked for Modular Computer
Systems (MODCOMP) in South Florida, the premier manufacturer
of real-time computers and real-time operating systems. His
software development efforts included enhancing the MODCOMP
real-time operating system, solo-efforts to develop a symbolic
debugger for FORTRAN77, a structured query language interpreter,
and source control management system, and finally managing
a software-test group.
Harry launched
his C++ career in the Dallas, Texas area in 1992 through his
work on a world-class symbolic debugger for Convex Computer
Corporation which was followed by challenging real-world
applications including embedded C++ applications for air-traffic
control, fuel-tank monitoring, wireless telemetry and computer-controlled respiratory ventilator systems. These have touched areas of Windows, UNIX,
MFC, sockets, multithreading, RTOSes, and numerous microntrollers.
Throughout his 25 years of software development experiences
in the South Florida and Dallas metroplexes, Harry was the
primary or secondary interviewer of over one hundred engineering
candidates.
Harry's personal
interests include his family, church and studying business
leadership issues.
|