MinGW SEH和MinGW SJLJ有什么区别?

vas*_*111 25 c c++ qt mingw

我刚刚开始学习C并安装现在的QT x64(在此处形成:http://tver-soft.org/qt64).我有两个安装选项:MinGW 4.9.2 SEHMinGW 4.9.2 SJLJ.
问题:安装哪个更好,为什么?

我读过sjlj vs dwarf vs seh之间有什么区别?https://wiki.qt.io/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF.2C_and_SEH但一无所知(C和compiller语言的新手).

App*_*les 29

SJLJ和SEH是两种不同的异常处理系统.

对于具体的差异,您已经看到的资源涵盖了一切.

但是,至于哪一个更好安装,除非您知道需要SEH,否则请使用SJLJ.

SJLJ

SJLJ在各种体系结构中得到更广泛的支持,并且更加强大.此外,可以通过使用其他异常处理系统(包括C库)的库抛出SJLJ异常.但是,它会降低性能.

SEH

SEH效率更高(没有性能损失),但遗憾的是没有得到很好的支持.SEH异常会在通过不使用SEH的库引发时导致不良事件发生.

就您的代码而言,没有真正的差异.如果需要,您可以随后切换编译器.

  • 更多解释 - 虽然通常不在C代码中使用,但异常是一种在不连续检查返回代码的情况下处理错误的方法.这在C++和大多数面向对象语言中很常见.遇到错误时,"抛出"异常类型,然后被其他一些代码捕获.在C++中,这是一个"实现"问题,这意味着它不是标准,因此不同的编译器可以采用不同的方式.当程序的不同部分(即库)以不同方式实现异常时,就会出现问题. (5认同)

小智 13

我在MinGW-w64中发现了SJLJ和SEH异常处理之间的一个区别:一旦在运行时至少有一个try {}块被执行,signal()函数设置的C信号处理程序在SJLJ版本中不起作用.由于这个问题似乎没有在任何地方描述,我将它放在这里作为记录.

以下示例(test_signals.cpp)演示了这一点.

// This sample demonstrates how try {} block disables handler set by signal()
// on MinGW-w64 with GCC SJLJ build
#include <signal.h>
#include <iostream>

int izero = 0;

static void SIGWntHandler (int signum)//sub_code)
{
  std::cout << "In signal handler, signum = " << signum << std::endl;
  std::cout << "Now exiting..." << std::endl;
  std::exit(1);
}

int main (void)
{
  std::cout << "Entered main(), arming signal handler..." << std::endl;
  if (signal (SIGSEGV, (void(*)(int))SIGWntHandler) == SIG_ERR)
    std::cout << "signal(OSD::SetSignal) error\n";
  if (signal (SIGFPE, (void(*)(int))SIGWntHandler) == SIG_ERR)
    std::cout << "signal(OSD::SetSignal) error\n";
  if (signal (SIGILL, (void(*)(int))SIGWntHandler) == SIG_ERR)
    std::cout << "signal(OSD::SetSignal) error\n";

  // this try block disables signal handler...
  try { std::cout << "In try block" << std::endl; } catch(char*) {}

  std::cout << "Doing bad things to cause signal..." << std::endl;
  izero = 1 / izero; // cause integer division by zero
  char* ptrnull = 0;
  ptrnull[0] = '\0'; // cause access violation

  std::cout << "We are too lucky..." << std::endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

构建:

g++ test_signals.cpp -o test_signals.exe
Run Code Online (Sandbox Code Playgroud)

预期的产出是:

Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
In signal handler, signum = 8
Now exiting...
Run Code Online (Sandbox Code Playgroud)

使用MigGW-w64 SJLJ变体构建时的实际输出是:

Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
Run Code Online (Sandbox Code Playgroud)

一段时间后,应用程序会以静默方式终止.也就是说,不会调用信号处理程序.如果try {}块被注释掉,则信号处理程序被正确调用.

使用MinGW-w64 SEH变体时,它的行为与预期一致(信号处理程序被调用).

我不清楚为什么会出现这个问题,如果有人能给出解释,我将不胜感激.