Je commence tout juste à apprendre le C et à installer maintenant QT x64 (formulaire ici: http://tver-soft.org/qt64 ). J'ai deux options à installer: MinGW 4.9.2 SEH
ou MinGW 4.9.2 SJLJ
.
Question: Quel est le meilleur à installer et pourquoi?
J'ai lu Quelle est la différence entre sjlj vs nain vs seh? et https://wiki.qt.io/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF. 2C_and_SEH mais ne comprends rien (nouveau dans les langages C et compilateur).
SJLJ et SEH sont deux systèmes de gestion des exceptions différents.
Pour les différences spécifiques, les ressources que vous avez déjà vues couvrent tout.
Cependant, quant à celui qui est meilleur à installer, allez avec SJLJ sauf si vous savez que vous avez besoin de SEH.
2019 Update: Sur les systèmes modernes, il n'y a aucune raison d'utiliser SJLJ, donc les conseils ci-dessus devraient probablement être inversés. SEH est plus courant maintenant. En fin de compte, cela n'a pas vraiment d'importance, car il est facile de basculer entre les deux.
SJLJ est plus largement pris en charge à travers les architectures et est plus robuste. De plus, les exceptions SJLJ peuvent être levées via les bibliothèques qui utilisent d'autres systèmes de gestion des exceptions, y compris les bibliothèques C. Cependant, il a une pénalité de performance.
SEH est beaucoup plus efficace (sans pénalité de performance), mais n'est malheureusement pas bien pris en charge. Les exceptions SEH provoquent de mauvaises choses lorsqu'elles sont lancées via des bibliothèques qui n'utilisent pas également SEH.
En ce qui concerne votre code, il n'y a pas de réelles différences. Vous pouvez toujours changer de compilateur plus tard si vous en avez besoin.
J'ai découvert une différence entre la gestion des exceptions SJLJ et SEH dans MinGW-w64: les gestionnaires de signaux C définis par la fonction signal () ne fonctionnent pas dans la version SJLJ dès qu'au moins un bloc try {} est exécuté au moment de l'exécution. Étant donné que ce problème ne semble être décrit nulle part, je le mets ici pour mémoire.
L'exemple suivant (test_signals.cpp) le démontre.
// 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;
}
Construit avec:
g++ test_signals.cpp -o test_signals.exe
Le résultat attendu est:
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
In signal handler, signum = 8
Now exiting...
La sortie réelle lorsque je crée avec la variante MigGW-w64 SJLJ est:
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
L'application se termine silencieusement après un certain délai. Autrement dit, le gestionnaire de signal n'est pas appelé. Si le bloc try {} est mis en commentaire, le gestionnaire de signal est correctement appelé.
Lorsque vous utilisez la variante MinGW-w64 SEH, elle se comporte comme prévu (le gestionnaire de signal est appelé).
Je n'ai pas une idée claire de la raison pour laquelle ce problème se produit, donc je serai reconnaissant si quelqu'un peut donner une explication.