Static locals are guaranteed to be instantiated at first use by the C++ standard. However, I'm wondering what happens if I access a static local object while it is beeing constructed. I assume that this is UB. But what are the best practices to avoid this in the following situation?
A problem situation
The Meyers Singleton pattern uses a static local in a static getInstance() method to construct the object on the first use. Now if the constructor (directly or indireclty) calls getInstance() again, we face
a situation where the static initialization is not yet completed. Here is a minimal example, that illustrates the problem situation:
class StaticLocal {
private:
    StaticLocal() {
        // Indirectly calls getInstance()
        parseConfig();
    }
    StaticLocal(const StaticLocal&) = delete;
    StaticLocal &operator=(const StaticLocal &) = delete;
    void parseConfig() {
        int d = StaticLocal::getInstance()->getData();
    }
    int getData() {
        return 1;
    }
public:
    static StaticLocal *getInstance() {
        static StaticLocal inst_;
        return &inst_;
    }
    void doIt() {};
};
int main()
{
    StaticLocal::getInstance()->doIt();
    return 0;
}
In VS2010, this works without problems, but VS2015 deadlocks.
For this simple, reduced situation, the obvious solution is to direclty call getData(), without calling getInstance() again. However, in more complex scenarios (as my actual situation), this solution is not feasible.
Attempting a solution
If we change the getInstance() method to work on a static local pointer like this (and thus abandon the Meyers Singleton pattern):
static StaticLocal *getInstance() {
    static StaticLocal *inst_ = nullptr;
    if (!inst_) inst_ = new StaticLocal;
    return inst_;
}
It is clear that we get an endless recursion. inst_ is nullptr on the first invokation, so we call the constructor with new StaticLocal. At this point, inst_ is still nullptr as it will only get assigned when
the constructor finishes. However, the constructor will call getInstance() again, finding a nullptr in inst_, and thus call the constructor again. And again, and again, ...
A possible solution is to move the constructor's body into the getInstance():
StaticLocal() { /* do nothing */ }
static StaticLocal *getInstance() {
    static StaticLocal *inst_ = nullptr;
    if (!inst_) {
        inst_ = new StaticLocal;
        inst_->parseConfig();
    }
    return inst_;
}
This will work. However, I'm not happy with this situation, as a constructor should, well, construct a complete object. It is debateable if this situation can be made an exception, as it is a singleton. However, I dislike it.
But what's more, what if the class has a non-trivial destructor?
~StaticLocal() { /* Important Cleanup */ }
In the above situation, the destructor is never called. We loose RAII and thus one important distinguishing feature of C++! We are in a world like Java or C#...
So we could wrap our singleton in some sort of smart pointer:
static StaticLocal *getInstance() {
    static std::unique_ptr<StaticLocal> inst_;
    if (!inst_) {
        inst_.reset(new StaticLocal);
        inst_->parseConfig();
    }
    return inst_.get();
}
This will correctly call the destructor on program exit. But it forces us to make the destructor public.
At this point, I feel I'm doing the compiler's job...
Back to the original question
Is this situation really undefined behaviour? Or is it a compiler bug in VS2015?
What is the best solution to such a situation, prefably without dropping a full constructor, and RAII?
 
     
     
     
     
     
     
     
    