如何将呼叫保持在线,但要避免编译器警告
How to keep calls inlined but avoid compiler warnings?
我有一个类,该类在我的软件中的所有代码中广泛使用。该类是具有某些几何函数的点抽象,并且通过坐标类型(例如长或double)进行模板。如果在动态库之间传递这一点,我会得到编译器警告 c4252:类"点"需要让'ethoterclass''''ofers'emotclass'的客户使用dll-interface 具有相同的编译设置。
由于我们的策略根本没有警告,我们决定标记两个广泛使用的模板专业dll,例如这样(在带有模板的标题中):
template class __declspec(dllexport) Point<long>;
template class __declspec(dllexport) Point<double>;
,但是现在编译器用常见的函数调用代替了所有嵌入式,并且由于大量使用了该类,我们的代码变慢了得多。
问题是:是否有任何方法可以在每个库中保留呼叫,但仍在使用DLL之间的数据并避免警告?
?我们使用Microsoft VC 2012编译器。
在我的经验中,如果速度是一个问题,我通过使用静态链接的代码/header仅inline
和fastcall
代码而不是DLL
s获得了更好的性能,但是您的描述是确切的原因,回想起来,我认为可能有某种方法可以实现您的意思,尽管我怀疑基准测试仍会显示静态链接的代码以保持更快。
我正在考虑强迫DLL
S在加载时间居住(并且确实可以按照文章在此处执行此操作),以便可以与内线/静态链接代码相似的性能成就了。
这似乎一开始就起作用,但是,如果在任何时候分类了DLL
的内存,它将变得像动态访问DLL
代码一样慢。
直到我研究了链接到 DLL
s的进一步方法,我个人会个人推荐 inline fastcall 代码,如果这是一种选项,尽管这会导致可执行文件更大,并且可能会影响您的发布内存足迹是一个问题。
作为您上面提到的两行的快速修复,您可以尝试更改:
template class __declspec(dllexport) Point<long>;
template class __declspec(dllexport) Point<double>;
to
extern template class __declspec(dllexport) Point<long>;
extern template class __declspec(dllexport) Point<double>;
应该希望删除您所遇到的问题。(有关此操作的更多信息,此处可在此页面上使用,用于导出包含STL类的STL类或似乎是同一问题的对象的实例)。
然而,内部(一个汇编阶段"优化")天生坐着的原理是从DLL导出/导入/导入的:前者通过将所有内容组合在一起,以优化速度,后者对内存足迹/模块化优化,以通过将代码分为不同的较小捆绑包,可以在需要时调用。
注意:
fastcall
将一个或多个参数放入寄存器中,从而减少执行所需的内存调用数量。- 对于MSOFT和GCC,当您只有2个参数时,您会获得最明显的速度好处。
- Borland编译器将允许使用多达3个寄存器/参数
- 还请注意,内联关键字不能保证代码将被绑架,这只是对编译器,但是其他优化标志可以将其删除或直列您未标记为内联的其他部分。
希望这会有所帮助,但是与往常一样,如果您需要更多信息/帮助,请告诉我。:)
- 如何修复编译器警告 C6386 和 C6385?
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 为什么布尔开关语句有编译器警告?
- 奇怪的缩小转换在 g++ 编译器中加倍到浮点警告
- 处理编译器关于可能丢失数据的警告的最优雅方法是什么
- 使用 reverse_iterator 而不是const_reverse_iterator并获得讨厌的编译器警告和错误
- 添加 c++11 编译器后打开 devc++ 时显示的警告
- 来自 std::chrono 的编译器警告,但未被使用
- 警告级别为 3 的 int 的 std::vector push_back 处的编译器警告
- G++ 编译器未为未定义的方法生成错误/警告
- 从 int 中剥离位时,编译器会警告一个转换,但不警告其他转换.有解决方法吗?
- 有没有办法在从临时返回按值string_view时获得编译器警告?
- 常量更改而不const_cast<> 为什么没有编译器警告/错误?
- 为什么编译器不在同一翻译单元中警告 ODR 违规
- C++语法错误,编译器不会警告或 int v = func(&v) 出错;
- C++ 添加编译器警告,以错误使用自定义打印/日志功能
- 我正在尝试在我的类中创建一个静态成员,但编译器警告我它是未定义的
- 是否可以将移动的变量标记为不再可用,并在使用它时收到编译器警告?
- 为什么我应该始终启用编译器警告
- 使用Boost :: black在boost :: variant中使用时,请警告编译器