En C et C++, quelle est la différence entre exit()
et abort()
? J'essaie de terminer mon programme après une erreur (pas une exception).
abort()
quitte votre programme sans appeler les fonctions enregistrées à l'aide de atexit()
d'abord, et sans appeler en premier les destructeurs des objets. exit()
fait les deux avant de quitter votre programme. Cependant, il n'appelle pas les destructeurs pour les objets automatiques. Alors
A a;
void test() {
static A b;
A c;
exit(0);
}
Détruit a
et b
correctement, mais n'appellera pas les destructeurs de c
. abort()
n'appelle pas les destructeurs ni des objets. Comme cela est regrettable, la norme C++ décrit un mécanisme alternatif qui assure une terminaison correcte:
Les objets à durée de stockage automatique sont tous détruits dans un programme dont la fonction
main()
ne contient aucun objet automatique et exécute l'appel deexit()
. Le contrôle peut être transféré directement à une tellemain()
en lançant une exception interceptée dansmain()
.
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
int main() {
try {
// put all code in here
} catch(exit_exception& e) {
exit(e.c);
}
}
Au lieu d'appeler exit()
, arrangez ce code throw exit_exception(exit_code);
à la place.
abort envoie un signal SIGABRT, exit ferme simplement l'application effectuant un nettoyage normal.
Vous pouvez gérer un signal abandon comme vous le souhaitez, mais le comportement par défaut consiste à fermer également l'application avec un code d'erreur.
abort n'effectuera pas la destruction d'objet de vos membres statiques et globaux, mais exit le fera.
Bien sûr, lorsque l’application est complètement fermée, le système d’exploitation libérera toute mémoire non libérée et autres ressources.
À la fois abandon et sortie arrêt du programme (si vous n'avez pas remplacé le comportement par défaut), le code de retour est renvoyé au processus parent qui a démarré votre application.
Voir l'exemple suivant:
SomeClassType someobject;
void myProgramIsTerminating1(void)
{
cout<<"exit function 1"<<endl;
}
void myProgramIsTerminating2(void)
{
cout<<"exit function 2"<<endl;
}
int main(int argc, char**argv)
{
atexit (myProgramIsTerminating1);
atexit (myProgramIsTerminating2);
//abort();
return 0;
}
Commentaires:
Si abort n'est pas commenté: rien n'est imprimé et le destructeur de certains objets ne sera pas appelé.
Si abort est commenté comme ci-dessus: un destructeur d'objet sera appelé, vous obtiendrez le résultat suivant:
fonction de sortie 2
Fonction de sortie 1
Les choses suivantes se produisent lorsqu'un programme appelle exit
():
atexit
sont exécutéestmpfile
sont supprimésLa fonction abort
() envoie le signal SIGABRT
au processus en cours. S'il n'est pas capturé, le programme est arrêté sans aucune garantie que les flux ouverts soient vidés/fermés ou que les fichiers temporaires créés via tmpfile
sont supprimés, atexit
les fonctions enregistrées ne sont pas appelées et un statut de sortie non nul est renvoyé à l'hôte.
Depuis la page de manuel exit ():
La fonction exit () provoque l'arrêt normal du processus et la valeur de l'état & 0377 est renvoyée au parent.
À partir de la page de manuel abort ():
La commande abort () débloque d'abord le signal SIGABRT, puis lève ce signal pour le processus appelant. Cela aboutit à une fin anormale du processus à moins que le signal SIGABRT soit capturé et que le gestionnaire de signal ne revienne pas.
abort
envoie le signal SIGABRT
. abort
ne revient pas à l'appelant. Le gestionnaire par défaut du signal SIGABRT
ferme l'application. Les flux de fichiers stdio
sont vidés puis fermés. Les destructeurs pour les instances de classe C++ ne sont pas, cependant (pas sûr pour celui-ci - peut-être que les résultats ne sont pas définis?).
exit
a ses propres rappels, définis avec atexit
. Si des rappels sont spécifiés (ou un seul), ils sont appelés dans l'ordre inverse de leur ordre d'enregistrement (comme une pile), puis le programme se ferme. Comme avec abort
, exit
ne revient pas à l'appelant. Les flux de fichiers stdio
sont vidés puis fermés. Les destructeurs pour les instances de classe C++ sont également appelés.