The instantiation process of function static variables isn't necessarily what you expect it to be. Raymond Chen posted a nice bit on this some time back (http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx). If you haven't read it, go do so now. I won't repeat it here.
At this point, there's a 90% chance that you've actually skipped the recommended read, so I'll go ahead and sum it up real quick. Yeah I know I said I wouldn't. I lied. Get on with your life. Anyhoo, here goes the five second recap ..
Consider the following function:
It seems simple enough, and it is. The static variable will be initialized once, based on the result of the function calcSomething. With non-volatile constant values, the compiler can optimize the generated code to use the memory address of the value. In this case, where a function is called, a function we know nothing about might I add, it doesn't necessarily have that luxury. Looking at the generated assembly code, we'll see something like thisvoid foo()
static int x = calcSomething();
Loosely translated to pseudo C++, this will bemov eax,1
test byte ptr [$S1],al
or dword ptr [$S1],eax
mov dword ptr [x)],eax
As you can see, there's no interlocking code here. This essentially means that function will be anything but thread safe. One thread may reach, but not execute, x_set = true, only to be swapped out in favor of another thread which does the same. The result would be that calcSomething is executed two or more times -- which is likely to be a bad thing.void foo()
static bool x_set = false;
static int x;
x_set = true;
x = calcSomething();
That's it for the recap. Now, if we'd like to fix this problem, what comes to mind? Interlocking, obviously...
This article can now be found at http://www.codeguru.com/cpp/misc/misc/threadsprocesses/article.php/c12897/.