Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VC++

How Local Static Variable Is Implemented in VC++

0.00/5 (No votes)
8 Apr 2009CPOL2 min read 14.7K  
How local static variable is implemented in VC++

As every one knows, static variables are initialized only once, even though it is declared in a function. In this post, I will explain how the compiler implements this.

OK, let's start with the storage of the static variables. Where do you think a static variable declared inside a function is stored? If your answer is on the stack, you are wrong. All static and global variables are stored in a section called ".data" in the EXE. For example, check the below code:

C++
int g_GlobalVariable = 0x10;
static int nValue1 = 0x11;
void main()
{
     static int nValue2 = 0x12;
     // Take the address

     int *pglobal = &g_GlobalVariable;
     int *pValue1 = &nValue1;
     int *pValue2 = &nValue2;
}

When executed, the values of pglobal, pValue1 and pValue2 were 0x408020, 0x408024 and 0x408028 respectively. Which means, all the three variables were stored in three consecutive locations. In the PE view, we can see these variables stored in the ".data" section.

You can see that the "nValue2" variable is initialized at the compile time itself. So no instruction is generated by the compiler for a statement like static int nValue2 = 0x12;

So, the compiler did a nice job by setting the value to variable at compile time itself. But that was a C type object. What if we declare a static C++ object inside a function. This time, the compiler cannot initialize the variable at compile time because the constructor needs to be invoked to initialize a C++ object. Consider the below code:

C++
class TestClass
{
public:
  TestClass()
  {
    m_nMemeberVar = 10;
  }
  int m_nMemeberVar;
};
TestClass& AFunction()
{
  static TestClass cppObject;
  return cppObject;
}

In the above code, the AFunction() function creates a static object of class TestClass and as you know, the cppObject will be initialized only once. How does the compiler manage to do it? Well, the answer is that the compiler keeps a flag!!!, i.e., when the compiler sees a C++, static object is declared inside a function, it will create a global byte variable with value 0 and some additional instruction such that the constructor of the object will be called only if the value of the byte variable is 0 and it also sets the value of the byte variable as 1. So from the next time onwards, the constructor will not be called. Below is the disassembly for the statement static TestClass cppObject.

C++
static TestClass cppObject;

// Zero out the eax register
00401E79   xor         eax,eax

// Copy the flag variable to al register
00401E7B   mov         al,[`AFunction'::`2'::$S230 (00408104)]
00401E80   and         eax,1

// Check eax equal to zero
00401E83   test        eax,eax

// If it is not zero, go to end.
00401E85   jne         AFunction+3Dh (00401ead)

// Copy the flag variable to the cl register
00401E87   mov         cl,byte ptr [`AFunction'::`2'::$S230 (00408104)]

// cl = 1
00401E8D   or          cl,1

// Copy back the content of cl register to the flag variable
00401E90   mov         byte ptr [`AFunction'::`2'::$S230 (00408104)],cl

// Call the constructor of cppObject
00401E96   mov         ecx,offset theApp+0C8h (00408100)
00401E9B   call        TestClass::TestClass (00401ec0)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)