防止链接器排除未引用的静态

时间:2012-08-04 17:19:38

标签: c++ visual-studio visual-studio-2008

我需要在列表中存储编译时类型信息(名称,字段...),我可以在运行时迭代。 我想出了一些看起来像这样的东西:

#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;
}

这样我需要做的就是声明一个新类型并同时静态注册它是在我的代码中的任何地方使用宏_DECLARE_TYPE。 上面的例子将输出:

A
float
unsigned int

在MSVC9上,一切正常,我得到输出,直到我开启优化,包括“消除未引用数据(/ OPT:REF)”。 如果我这样做,上面的程序没有输出。 现在我看到TypeHolder,TypeHolder,TypeHolder没有在代码中直接引用,所以我想联系人正在删除它们,无论它们的初始化可能有任何副作用。 我使用静态初始化的原因是它允许我在我的代码中的任何地方声明和注册一个类型,而不必创建一个我手动调用的大函数

TypeList::Push(TypeHolder<unsigned int>::ms_kType);
TypeList::Push(TypeHolder<float>::ms_kType);
TypeList::Push(TypeHolder<A>::ms_kType);

每种类型。

此外,我希望我的解决方案适用于各种编译器,因此使用非标准的#pragma指令只能在MSVC上工作,甚至不能关闭优化。

我有什么方法可以避免在一个单独的地方(除宏内部)手动列出所有类型的麻烦吗?

0 个答案:

没有答案