Q: Preventing linker from excluding unreferenced static I have the need to store compile time type information (name, fields...) inside a list that i can iterate through at run time.
I've come up with something that looks like this:
#include <stdio.h>

struct Type
{
    const char *m_szName;
    Type *m_pNext;
};

struct TypeList
{
    static Type *ms_pHead;

    static Type *Push(Type *pHead)
    {
        Type *pNext(ms_pHead);
        ms_pHead = pHead;
        return pNext;
    }
};

Type *TypeList::ms_pHead = 0;

template <typename T>
struct TypeHolder
{
    static Type ms_kType;
};

#define _DECLARE_TYPE(_Name) \
    template <> Type TypeHolder<_Name>::ms_kType = {#_Name, TypeList::Push(&ms_kType)};

struct A
{
    float m_fField;
};

_DECLARE_TYPE(unsigned int);
_DECLARE_TYPE(float);
_DECLARE_TYPE(A);

int main()
{
    Type *pType(TypeList::ms_pHead);
    while (pType != 0)
    {
        printf("%s\n", pType->m_szName);
        pType = pType->m_pNext;
    }
    return 0;
}

This way all i need to do to declare a new type and register it statically at the same time is use the macro _DECLARE_TYPE anywhere in my code.
The above example would output:
A
float
unsigned int

On MSVC9 everything works fine and i get output until i turn optimizations on, which include "Eliminate Unreferenced Data (/OPT:REF)".
If i do that, the program above has no output.
Now i see that TypeHolder, TypeHolder, TypeHolder are not referenced directly in the code, so i imagine that the linker is removing them regardless of any side effects their initialization might have.
The reason why i used static initialization is that it allows me to declare and register a type anywhere in my code without having to create a big function that i manually call that would do
TypeList::Push(TypeHolder<unsigned int>::ms_kType);
TypeList::Push(TypeHolder<float>::ms_kType);
TypeList::Push(TypeHolder<A>::ms_kType);

for each type.
Also, i would like my solution to work on a wide range of compilers, so using non-standard #pragma directives that only work on MSVC or even turning optimizations off is not an option.
Is there any way for me to avoid the hassle of having to manually list all the types in a separate place (other than inside the macro)?
