sjlj vs dwarf vs seh有什么区别?

sor*_*h-r 135 c++ compiler-construction mingw cpu-architecture mingw-w64

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

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

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

注意事项:

  • 编译时间和内存对我的使用并不重要.唯一重要的是运行时优化.我需要我的程序足够快.慢编译器是可以接受的.
  • 操作系统:Microsoft Windows XP/7/8/Linux
  • 架构:英特尔酷睿i7/Core2 /以及运行XP:P的非常老的i686

oll*_*llo 98

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

为什么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跳远踏板的异常处理方法适用于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).[...] 不幸的是,海湾合作委员会尚未支持SEH.[...]

也可以看看:

  • 谢谢你的链接.我打算将DW2用于32位,SEH用于64. SEH可用于mingwbuilds(4.8).我应该等待4.8的稳定释放还是没问题?它编译在这里.我目前正在使用带有SEH的4.8来创建项目的依赖项.没有问题...... (7认同)
  • @woreos我使用自己的Qt构建.我发现Qt和GCC 4.8都没有问题.这是我的半烧RAM![1](http://superuser.com/questions/575482/install-windows-8-for-second-time-failed)现在一切正常 (4认同)
  • 所有依赖项(包括Boost库,OpenSSL,ICU,freeGLUT)都已编译但Qt最终会出现大量内部编译器错误.我想我会等待4.8的稳定发布 (2认同)

小智 75

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

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

SEH(零开销异常) - 将适用于64位GCC 4.8.

来源:http://qt-project.org/wiki/MinGW-64-bit

  • 所以现在在2016年我们可以暂时搁置这个问题,并且总是使用SEH. (11认同)
  • @RustyX仅当您的目标是x86_64时 (6认同)
  • 抱歉,添加了源链接. (2认同)
  • 感谢您的回答 ;) (2认同)
  • 那么 x86 的 Dwarf 呢? (2认同)