编译器优化-函数没有地址

时间:2019-01-27 13:57:56

标签: c++ optimization visual-studio-2015 static-libraries

一段时间以来,我是C ++开发人员,但是我没有使用太多指向成员函数的指针。使用此类指针时,我已经发现一些危险的情况。我需要一些有更多经验的同事来进一步解释它,因为调试和分析不是那么容易。

由于某些优化,编译器决定不为功能分配地址时,就会出现问题。甚至在Debug,x86(禁用了优化-/ Od)的情况下,VS 2015发生在我身上。我正在重构一个旧系统,并在一个公共静态库(common.lib)中移动了一些代码,以便可以在多个项目中使用。即使不是最佳模式,旧的实现也严重依赖于函数成员指针,因此我现在不想更改它。例如,我将接口ModuleBase添加到一个非常大的旧类中,例如:

class ModuleBase
{
public:
    typedef void (ModuleBase::*Main)() const;  // moved from old module

    virtual void FunctionMain() const = 0;  //  Function has no address, possibly due to compiler optimizations.    
    virtual void FunctionSecondary() const = 0;  // Function has no address, possibly due to compiler optimizations.
};


class OldModule : public ModuleBase
{
public:
    virtual void FunctionMain() const {};
    virtual void FunctionSecondary() const {};
}

想法是将ModuleBase移到静态库中,但将OldModule保留在主EXE项目中。当ModuleBase在主项目中时,它运行良好,但是当我在静态Common.lib中移动它时,它开始崩溃!我花了大约两天的时间才终于注意到,在几个地方,编译器决定(但仅针对静态库)决定不从ModuleBase分配地址给FunctionMain,FunctionSecondary()等。因此,当将这些虚拟函数的指针传递给其他例程时,它们为零。

例如下面的代码:

new Manager::ModuleDecription(
        "Test Module",
        "Secondary Scene",
        "Description"
         PosX,
         PosY,
         Proc,
         &ModuleBase::FunctionSecondary   //contains nullptr when in static library!!!!!

结构中的最后一个成员为零,但只有在静态库中时才为零。这很讨厌,因为我必须先检查许多其他事项才能注意到这一点。另外还有其他一些指针不为零,因为该结构未在构造函数中清零,因此必须注意地址值不同,并在尝试调用该函数时崩溃。

所以我的问题是- 1)我是否看到这种权利-这是正确的情况吗(对于相同的代码,但在静态库中移动时,编译器正在删除上述情况下的函数地址)?

2)如何强制编译器始终保留成员函数地址?

1 个答案:

答案 0 :(得分:0)

抱歉,我发现Visuals Studio中指向成员函数的指针的地址没有问题。基本接口虚拟函数的指针可以解析,即使放在静态库中也可以。我遇到问题的原因是:

1)调试器有时会将模板类的函数地址显示为零

2)崩溃的原因是主项目具有 / vmg 编译器选项,但我没有将其放入静态库项目中。在这种情况下,应该小心在所有引用的库项目中始终使用 / vmg (由于这是另一个主题,因此很复杂)。

无论如何,将指向成员的指针函数与对象指针一起使用通常是底层设计不良的标志。

我希望这可以对某人有所帮助。