164

我找不到足够的信息来决定应该使用哪个编译器来编译我的项目。在不同的计算机上有几个程序模拟一个过程。在 Linux 上,我使用的是 GCC。一切都很好。我可以优化代码,它编译速度快并且使用的内存不多。

我用 MSVC 和 GCC 编译器做我自己的基准测试。后来的一个产生稍微快一点的二进制文件(对于每个子架构)。虽然编译时间远远超过 MSVC。

所以我决定使用MinGW。但是在MinGW中找不到关于异常处理方法及其实现的任何解释。我可以为不同的操作系统和架构使用不同的发行版。

注意事项:

  • 编译时间和内存对我的使用并不重要。唯一重要的是运行时优化。我需要我的程序足够快。慢速编译器是可以接受的。
  • 操作系统:微软 Windows XP / 7 / 8 / Linux
  • 架构:Intel Core i7 / Core2 / 和运行 XP 的非常旧的 i686:P
4

2 回答 2

119

MinGW-w64 Wiki上有一个简短的概述:

为什么 mingw-w64 gcc 不支持 Dwarf-2 异常处理?

Windows的Dwarf-2 EH实现根本不是为在 64 位 Windows 应用程序下工作而设计的。在 win32 模式下,异常展开处理程序无法通过不支持 dw2 的代码传播,这意味着通过任何不支持 dw2 的“外帧”代码的任何异常都会失败,包括 Windows 系统 DLL 和使用 Visual Studio 构建的 DLL。gcc 中的 Dwarf-2 展开代码检查 x86 展开程序集,如果没有其他 dwarf-2 展开信息,则无法继续。

异常处理的SetJump LongJump方法适用于 win32 和 win64 上的大多数情况,但一般保护错误除外。正在开发 gcc 中的结构化异常处理支持以克服 dw2 和 sjlj 的弱点。在 win64 上,展开信息放置在 xdata-section 中,并且存在 .pdata(函数描述符表)而不是堆栈。对于 win32,处理程序链在堆栈上,需要由实际执行的代码保存/恢复。

GCC GNU关于异常处理

GCC 支持两种异常处理 (EH) 方法:

  • DWARF-2 (DW2) EH,需要使用 DWARF-2(或 DWARF-3)调试信息。DW-2 EH 可能导致可执行文件略微膨胀,因为大型调用堆栈展开表必须包含在可执行文件中。
  • 一种基于setjmp/longjmp (SJLJ)的方法。基于 SJLJ 的 EH 比 DW2 EH 慢得多(即使在没有引发异常时也会惩罚正常执行),但可以跨未使用 GCC 编译或没有调用堆栈展开信息的代码工作。

[...]

结构化异常处理 (SEH)

Windows 使用自己的异常处理机制,称为结构化异常处理 (SEH)。[...] 不幸的是,GCC 还不支持 SEH。[...]

也可以看看:

于 2013-03-28T15:03:34.117 回答
89

SJLJ (setjmp/longjmp): – 适用于 32 位和 64 位 – 不是“零成本”:即使没有抛出异常,它也会导致轻微的性能损失(在异常繁重的代码中约为 15%) – 允许异常遍历例如 windows 回调

DWARF (DW2, dwarf-2) – 仅适用于 32 位 – 没有永久的运行时开销 – 需要整个调用堆栈启用 dwarf,这意味着异常不能被抛出,例如 Windows 系统 DLL。

SEH(零开销异常)——将可用于 64 位 GCC 4.8。

来源:https ://wiki.qt.io/MinGW-64-bit

于 2013-03-27T21:55:02.167 回答