我刚刚开始学习C并立即安装QT x64(在此处形成:http://tver-soft.org/qt64)。我有两种安装选项:MinGW 4.9.2 SEH
或MinGW 4.9.2 SJLJ
。
问题:安装哪个更好,为什么?
我读过What is difference between sjlj vs dwarf vs seh?和https://wiki.qt.io/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF.2C_and_SEH但却一无所知(C和compiller语言的新手)。
答案 0 :(得分:24)
SJLJ和SEH是两种不同的异常处理系统。
对于具体的差异,您已经看到的资源涵盖了所有内容。
但是,至于哪一个更好要安装,使用 SJLJ ,除非您知道需要SEH。
2019更新:在现代系统上,没有理由使用SJLJ,因此上面的建议可能会被翻转。 SEH现在更常见。最终,它并不重要,因为它很容易在两者之间切换。
SJLJ在架构中得到更广泛的支持,并且更加强大。此外,可以使用其他异常处理系统(包括C库)将通过库抛出SJLJ异常。但是,它会降低性能。
SEH效率更高(没有性能损失),但遗憾的是没有得到很好的支持。 SEH异常将导致通过不使用SEH的库抛出不良事件。
就您的代码而言,没有真正的差异。如果需要,您可以随时切换编译器。
答案 1 :(得分:11)
我发现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;
}
构建:
g++ test_signals.cpp -o test_signals.exe
预期输出为:
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变体时,它的行为与预期一致(信号处理程序被调用)。
我不清楚为什么会出现这个问题,如果有人能给出解释,我将不胜感激。