Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ MinGW SEH和MinGW SJLJ之间有什么区别?_C++_C_Qt_Mingw - Fatal编程技术网

C++ MinGW SEH和MinGW SJLJ之间有什么区别?

C++ MinGW SEH和MinGW SJLJ之间有什么区别?,c++,c,qt,mingw,C++,C,Qt,Mingw,我刚刚开始学习C,现在正在安装QtX64(这里的表单:)。我有两个安装选项:mingw4.9.2seh或mingw4.9.2sjlj。 问题:安装哪个更好,为什么 我读过,但什么也不懂(对C和编译器语言来说是新的)。SJLJ和SEH是两种不同的异常处理系统 对于具体的差异,您已经看到的资源涵盖了所有内容 但是,如果您不知道需要SEH,请使用SJLJ安装哪一个更好 2019年更新:在现代系统上,没有理由使用SJLJ,因此上述建议可能会被推翻。SEH现在更为常见。但最终,这并不重要,因为在两者之间切

我刚刚开始学习C,现在正在安装QtX64(这里的表单:)。我有两个安装选项:
mingw4.9.2seh
mingw4.9.2sjlj

问题:安装哪个更好,为什么


我读过,但什么也不懂(对C和编译器语言来说是新的)。

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

对于具体的差异,您已经看到的资源涵盖了所有内容

但是,如果您不知道需要SEH,请使用SJLJ安装哪一个更好

2019年更新:在现代系统上,没有理由使用SJLJ,因此上述建议可能会被推翻。SEH现在更为常见。但最终,这并不重要,因为在两者之间切换很容易

SJLJ SJLJ在整个体系结构中得到更广泛的支持,并且更健壮。此外,SJLJ异常可以通过使用其他异常处理系统(包括C库)的库抛出。但是,它有一个性能惩罚

塞赫 SEH的效率要高得多(没有性能损失),但不幸的是,它没有得到很好的支持。当通过不使用SEH的库抛出时,SEH异常会导致不好的事情发生


就代码而言,没有真正的区别。如果需要,您可以随时切换编译器。

我在MinGW-w64中发现了SJLJ和SEH异常处理之间的一个区别:只要在运行时执行至少一个try{}块,signal()函数设置的信号处理程序就不会在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;
}
预期产出为:

Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
In signal handler, signum = 8
Now exiting...
使用MigGW-w64 SJLJ变体构建时的实际输出为:

Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
应用程序会在延迟一段时间后以静默方式终止。也就是说,不会调用信号处理程序。如果try{}块被注释掉,信号处理程序将被正确调用

当使用MinGW-w64 SEH变量时,它的行为符合预期(调用信号处理程序)


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

对于那些投票决定关闭它的人来说,对于一个新程序员来说,这是一件非常合理的事情。MinGW的两个版本之间的差异完全基于新用户无法理解的概念。更多说明——虽然通常不在C代码中使用,但异常是一种处理错误的方法,无需不断检查返回代码。这在C++和大多数面向对象语言中都是常见的。当遇到错误时,“抛出”异常类型,然后被其他代码捕获。在C++中,处理的是一个“实现”问题,这意味着它不是标准,因此不同的编译器可以不同地进行。当程序的不同部分(即库)不同地执行异常时,问题就出现了。@ NATEGOSE“这在C++和大多数面向对象语言中都是常见的”,而且不仅如此,即使是功能性的和(是的)逻辑编程语言也有例外。在这里,我们安装了一个工具,使程序员能够轻松地处理那些“特殊情况”,这些“特殊情况”需要被推到实际能够处理它们的某个部分。
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...