MinGW SEH 和 MinGW SJLJ 有什么区别?
What is the difference between MinGW SEH and MinGW SJLJ?
我刚开始学习 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? and https://wiki.qt.io/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF.2C_and_SEH 但什么都不懂(C 语言和编译器语言的新手)。
SJLJ 和 SEH 是两个不同的异常处理系统。
具体的区别,你看过的资源都涵盖了。
但是,至于安装哪个更好,选择SJLJ除非你知道你需要SEH.
2019 年更新: 在现代系统上,没有理由使用 SJLJ,因此上面的建议可能应该被翻转。 SEH 现在更常见了。不过归根结底,这并不重要,因为在两者之间切换很容易。
SJLJ
SJLJ 跨体系结构得到更广泛的支持,并且更健壮。此外,可以通过使用其他异常处理系统(包括 C 库)的 库 抛出 SJLJ 异常。但是,它会降低性能。
SEH
SEH 效率更高(没有性能损失),但不幸的是没有得到很好的支持。当通过不使用 SEH 的库抛出 SEH 异常时,会导致不好的事情发生。
就您的代码而言,没有真正的区别。如果需要,您以后可以随时切换编译器。
我在 MinGW-w64 中发现了 SJLJ 和 SEH 异常处理之间的一个区别:只要至少一个 try{} 块在 运行时间。由于这个问题似乎没有任何描述,所以我把它放在这里记录。
以下示例 (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] = '[=10=]'; // 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 变体时,它的行为符合预期(调用信号处理程序)。
我不清楚为什么会出现这个问题,如果有人能给出解释,将不胜感激。
我刚开始学习 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? and https://wiki.qt.io/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF.2C_and_SEH 但什么都不懂(C 语言和编译器语言的新手)。
SJLJ 和 SEH 是两个不同的异常处理系统。
具体的区别,你看过的资源都涵盖了。
但是,至于安装哪个更好,选择SJLJ除非你知道你需要SEH.
2019 年更新: 在现代系统上,没有理由使用 SJLJ,因此上面的建议可能应该被翻转。 SEH 现在更常见了。不过归根结底,这并不重要,因为在两者之间切换很容易。
SJLJ
SJLJ 跨体系结构得到更广泛的支持,并且更健壮。此外,可以通过使用其他异常处理系统(包括 C 库)的 库 抛出 SJLJ 异常。但是,它会降低性能。
SEH
SEH 效率更高(没有性能损失),但不幸的是没有得到很好的支持。当通过不使用 SEH 的库抛出 SEH 异常时,会导致不好的事情发生。
就您的代码而言,没有真正的区别。如果需要,您以后可以随时切换编译器。
我在 MinGW-w64 中发现了 SJLJ 和 SEH 异常处理之间的一个区别:只要至少一个 try{} 块在 运行时间。由于这个问题似乎没有任何描述,所以我把它放在这里记录。
以下示例 (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] = '[=10=]'; // 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 变体时,它的行为符合预期(调用信号处理程序)。
我不清楚为什么会出现这个问题,如果有人能给出解释,将不胜感激。