Chaining static objects with static linked list

The Problem

Every C++ book nowadays would tell you to avoid using static variables, or at least, avoid defining static variables that depend on each other. However, in some cases they are just irreplaceable: When we rely on the side-effect of static object initialization instead of having a centralized point for management, so that tight coupling can be avoided. This is typically the case for unit tests, as they are often defined in multiple compilation units, and are automatically registered to "the system" through construction. Here the problem arises: how do we store references to static instances?

Static Linked List

Since the initialization order of static objects across different compilation units is undefined, we can not count on containers using dynamic allocation such as std::vector, as they themselves can be uninitialized when being used.

A simple way would be using the static object themselves to form an intrusive linked list:

class MyClass  
{
public:  
    static MyClass* head;
    static MyClass* tail;
    MyClass* next;

    //automatically inserts new instance to the list
    MyClass() : next()
    {
        if (!tail)
        {
            head = tail = this;
        }
        else
        {
            tail->next = this;
            tail = this;
        }
    }
};

//some global variables
static MyClass g_MyInstance1;  
static MyClass g_MyInstance2;  
static MyClass g_MyInstance3;

//iterate through all MyClass instances
void IterateThroughMyClass()  
{
    for (MyClass* p = MyClass::head; p != nullptr; p = p->next)
    {
        //do stuff with p->
    }
}
Generic CRTP Base

Obviously we are smarter than just that. Why not turn the linked list into a base class?

template<class T>  
class StaticList  
{
public:  
    static T* head;
    static T* tail;
    T* next;

    //automatically inserts new instance to the list
    StaticList() : next()
    {
        T* thisNode = static_cast<T*>(this);
        if (!tail)
        {
            head = tail = thisNode;
        }
        else
        {
            tail->next = thisNode;
            tail = thisNode;
        }
    }
};

class MyClass : public StaticList<MyClass>{ /* stuff */ };  
class MyDerivedClass : public MyClass { /* stuff */ };

//in a.cpp
static MyClass g_MyInstance1; //in a.cpp

//in b.cpp
static MyDerivedClass g_MyInstance2;

//in user.cpp
//iterate through all MyClass instances
void IterateThroughMyClass()  
{
    for (MyClass* p = MyClass::head; p != nullptr; p = p->next)
    {
        //do stuff with p->
    }
}

The iteration part can be wrapped into an iterator type, and range based for loop if we really want to. Now we have a type MyClass whose instances automatically make up an intrusive linked list. Polymorphism is granted too. There is yet one problem: MyClass needs to inherit from a CRTP base, StaticList<MyClass>, which is not straightforward for many novice users. The inheritance also limits the design choices of MyClass, if we don't want it to multi-inherit from the CRTP and another base class.

Instance Wrapper

If we take into account, that the initialization order of static object within a compilation unit is defined as the declaration order, it's possible to turn inheritance relationship into owning. By constructing a linked node wrapper from the static object, we avoid writing the ugly mixin inheritance.

template<class T>  
class LinkedNode  
{
public:  
    const T& object;

    static LinkedNode<T>* head;
    static LinkedNode<T>* tail;
    LinkedNode<T>* next;

    //automatically inserts new instance to the list
    LinkedNode(const T& inObject) : object(inObject), next()
    {
        if (!tail)
        {
            head = tail = this;
        }
        else
        {
            tail->next = this;
            tail = this;
        }
    }
};

static MyDerivedClass g_MyObject;

//automatically connects to other LinkedNode<MyClass>
//can hold object reference of any descendant class
static LinkedNode<MyClass> g_MyObjectNode { g_MyObject };

void Iterate()  
{
    for (LinkedNode<MyClass>* p = LinkedNode<MyClass>::head; p != nullptr; p = p->next)
    {
        //do something with p->object
    }
}
Singleton Container

But if our problem was actually static initialization order fiasco between the objects and the container variable, wouldn't it be much cleaner if we wrap the container into a singleton?

//somewhere in .h
class MyClass  
{
    //other members
public:  
    static std::vector<MyClass*>& Instances()
    {
        static std::vector<MyClass*> m_Instances;
        return m_Instances;
    }

    MyClass() //init other members
    {
        Instances().push_back(this);
    }
};

class MyDerivedClass : public MyClass { /* ... */ }

//somewhere in .cpp
static MyClass g_MyInstance1;

//somewhere in another .cpp
static MyDerivedClass g_MyInstance2;

//usage
void Iterate()  
{
    for (MyClass* instance : MyClass::Instances())
    {
        //do stuff with instance->
    }
}

Note there could be a subtle problem with local static that can be solved by using new instead.

Conclusion

The examples above have shown several ways to store global variable references. Which one is more proper depends a lot on use case, and personal taste. The singleton approach seems cleanest among all, and is trivial to write once you know how it works. The static linked list requires implementing a non-trivial append function (and a removal function if that is required), which can get annoying when it has to be implemented for multiple types. It can be improved by using a generic wrapper, but the usage still looks tricky and comes with learning cost.