today I have another small C++ gotcha I wanted to draw your attention to. And I'll demonstrate it with a singleton (In case you don't know what a singleton is, I suggest you google it as quickly as possible and than clear your browser cache so nobody will find out you didn't know).
Let's take a look at the following code:
class MySingleton
{
public:
inline static MySingleton& getInstance()
{
// Create the instance via lazy initialization
static MySingleton instance;
return instance;
}
void foo() const;
protected:
MySingleton(){};
MySingleton( const MySingleton& ){};
};
// mySingleton.cpp
void MySingleton::foo() const
{
std::clog << "MySingleton::foo() was called" << std::endl;
}
Now, this looks just fine, and theoretically we should be able to use it as we are used to:
// Call foo() on our singleton
MySingleton::getInstance().foo();
And you can, and it should work fine. Until you use it from another module and make foo() access a data member of your singleton, that is.
So what's gone wrong here? Well, the culprit is the inline keyword in the declaration of the getInstance() function. Since the function is inlined, some compilers will actually create multiple instances of the static MySingleton instance, thus resulting in different objects being returned for different calls.
So the bottom line is: Be careful with static local variables inside of inline functions. They can lead to bugs that are really hard to track.
Happy coding :)