C++ 如何在VC++;2015年全程序优化
最近,我们在从VS2010移植到VS2015的遗留代码中遇到了一个有趣的效果。不幸的是,我无法创建一个小示例来显示这种效果,但我会尽可能准确地描述它 我们有两个dll(我称它们为dll A和dll B)。dll A的项目定义了接口IFoo&派生接口IFxFooC++ 如何在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
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的一部分的函数时,使用