C++ 如何在VC++;2015年全程序优化

C++ 如何在VC++;2015年全程序优化,c++,visual-c++,visual-c++-2015,C++,Visual C++,Visual C++ 2015,最近,我们在从VS2010移植到VS2015的遗留代码中遇到了一个有趣的效果。不幸的是,我无法创建一个小示例来显示这种效果,但我会尽可能准确地描述它 我们有两个dll(我称它们为dll A和dll B)。dll A的项目定义了接口IFoo&派生接口IFxFoo class __declspec(novtable) IFoo { public: virtual int GetType() = 0; virtual ~IFoo() {} }; class __declspec(no

最近,我们在从VS2010移植到VS2015的遗留代码中遇到了一个有趣的效果。不幸的是,我无法创建一个小示例来显示这种效果,但我会尽可能准确地描述它

我们有两个dll(我称它们为dll A和dll B)。dll A的项目定义了接口IFoo&派生接口IFxFoo

class __declspec(novtable) IFoo {
public:
    virtual int GetType() = 0;
    virtual ~IFoo() {}
};

class __declspec(novtable) IFxFoo : public IFoo {
public:
    virtual int GetSlot() = 0;
};
在dll B中,两个接口都使用

class CBImpl : public IFxFoo {
public:
    ...
    void processFoo(IFoo* f) {
        ...
        if (f->GetType() == IFXFOO) {
            IFxFoo* fx = static_cast<IFxFoo>(f); //downcast
            fill(fx);
        }
    }

    void fill(IFxFoo* fx) {
        m_slot = fx->GetSlot();
    }
private:
    int m_slot;
};
类CBImpl:public IFxFoo{ 公众: ... void processFoo(IFoo*f){ ... if(f->GetType()==IFXFOO){ IFxFoo*fx=static_cast(f);//向下播放 填充(外汇); } } 填空(IFxFoo*fx){ m_slot=fx->GetSlot(); } 私人: int m_槽; }; processFoo()将使用不同的IFoo实现进行调用。有些来自dll A,有些来自dll B

现在发生的情况如下: 如果在编译DLL B时打开整个程序优化,则在VisualC++中调用函数FILE()中的虚函数GETSLUTE()。这导致我们的程序崩溃。 如果我们

  • 全程序优化的转折点
  • 填充的优化回合
  • 或者用u declspec(dllimport)/u declspec(dllexport)标记我们的接口
我现在的问题是:

  • 我们的假设是否正确,因为优化器在dll B中只看到了一个IFxFoo实现,并且假设这是唯一一个IFxFoo实现,因为IFxFoo没有标记为来自不同的dll
  • 在头文件中创建“接口”的最佳方法是什么?我们过去经常这样做,但这似乎会导致一些问题
  • 其他编译器(gcc/clang)是否表现出类似的行为
谢谢你的帮助
Tobias

使用LTO会导致编译器对任何能够看到完整调用图的函数进行剧烈调整

你所看到的是期望的,在使用一个单独的模块或显式声明它们作为DLL的一部分的函数时,使用 Extn>代码> DEF文件是解决该问题的期望方式,因为编译器将不再考虑函数仅是内部的。