Saturday, March 26, 2011

Command line life in microsoft

Before I joined microsoft, I expected to use all the fancy tools from microsoft, but it turned out it is not the case, at least in my department. We used visual studio as a nice editing tool and sometimes used it for debugging. But we still spent a lot of time in command line working with source repository and building etc. We also need to work a lot on windows shell script too.

I am totally fine with that -- I am used to working in command line and 90% of my time was spent in putty in yahoo. But windows command line env (even cygwin) is much worse than linux shell session; windows shell scripting is even worse than linux shell scripting. For the shell one, I do not want to complain too much as I think this is probably because I am not familiar with windows shell. But the command line env, I guess everybody should agree with me. It also lacks a lot of handy linux shell utilities. My productivity is at least 50% worse than linux ;=(

be aware of the static variable in inline functions

I've learned a lesson Friday when debugging a test case -- the static variable in inline function is not always static.

Here is the use case. I have a singleton impl in a dll like below. In the DLL, I created a singleton instance and in my main program I also referred my singleton instance using Singleton::Instance(). Well it turned out that the instance referred in main program is different from the one created in the DLL!

// some .h file
class Singleton 
{
      T& Instance()  
      {
           static T  instance;
           return instance;
      }
};

// some cpp file

Singleton m_t = Singleton::Instance();


Why would it happen and how to resolve it?

  • If the singleton is in a static library, this is OK. 
  • DLL is same as exe that they are a standalone linker unit, which means they are complete -- all symbols have to be resolved, while static library is not. So when static variable is in the inline function and the function is invoked in a linker unit, a storage is allocated by the linker for that static variable. In my case, I have two linker units, so I have two copies of that instance.
  • Solution 1: do not inline
  • Solution 2: export the static variable in DLL and import it in the main program. A common way in visual c++ is like below

// in dll

// stdafx.h
#define MYAPI __declspec(dllexport)

// header file singleton.h
class MYAPI Singleton (};

# in other linker units

// stdafx.h
#ifndef MYAPI
#define MYAPI __declspec(dllimport)
#endif

// cpp of header file

#include "stdafx.h"
#include "singleton.h"