En C et C++, quelle est la différence entre exit()
y abort()
? J'essaie de terminer mon programme après une erreur (pas une exception).
Réponses
Trop de publicités?abort()
quitte votre programme sans appeler les fonctions enregistrées à l'aide de atexit()
d'abord, et sans appeler les destructeurs des objets d'abord. exit()
fait les deux avant de quitter votre programme. En revanche, il n'appelle pas les destructeurs des objets automatiques. Donc
A a;
void test() {
static A b;
A c;
exit(0);
}
Détruira a
y b
correctement, mais n'appellera pas les destructeurs de c
. abort()
n'appellerait pas les destructeurs de ces deux 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 àexit()
. Le contrôle peut être transféré directement à un telmain()
en lançant une exception qui est attrapé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.
abandonner envoie un signal SIGABRT, quitter ferme simplement l'application en effectuant un nettoyage normal.
Vous pouvez traiter un abandonner signalez ce que vous voulez, mais le comportement par défaut est de fermer l'application également avec un code d'erreur.
abandonner n'effectuera pas la destruction d'objet de vos membres statiques et globaux, mais quitter volonté.
Bien entendu, lorsque l'application est complètement fermée, le système d'exploitation libère toute la mémoire et les autres ressources non libérées.
Dans les deux cas abandonner y quitter la fin du programme (en supposant que vous n'avez pas modifié le comportement par défaut), le code de retour sera 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 abandonner est décommenté : rien n'est imprimé et le destructeur d'un objet ne sera pas appelé.
-
Si abandonner est commenté comme ci-dessus : le destructeur d'un 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
() :
- Fonctions enregistrées par le
atexit
sont exécutées - Tous les flux ouverts sont vidés et fermés, les fichiers créés par les
tmpfile
sont supprimés - Le programme se termine avec le code de sortie spécifié à l'hôte.
El abort
() envoie la fonction SIGABRT
au processus en cours, s'il n'est pas pris, le programme est terminé sans 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 état de sortie non nul est renvoyé à l'hôte.
Depuis la page de manuel exit() :
La fonction exit() provoque la fin normale du processus et la valeur de status & 0377 est retournée au parent.
Depuis la page de manuel abort() :
La fonction abort() débloque d'abord le signal SIGABRT, puis lève ce signal pour le processus appelant. signal pour le processus appelant. Cela entraîne la fin anormale du processus, à moins que le signal SIGABRT ne soit capté et que le gestionnaire du signal ne revienne pas. signal ne revienne pas.
abort
envoie le SIGABRT
signal. abort
ne retourne pas à l'appelant. Le gestionnaire par défaut de la fonction SIGABRT
ferme l'application. stdio
Les flux de fichiers sont vidés, puis fermés. Les destructeurs des instances de classes C++ ne le sont pas, cependant (je ne suis pas sûr de cela -- peut-être que les résultats sont indéfinis ?)
exit
a ses propres rappels, définis avec atexit
. Si des callbacks 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 termine. Comme avec abort
, exit
ne revient pas à l'appelant. stdio
les flux de fichiers sont vidés, puis fermés. Les destructeurs des instances de classes C++ sont également appelés.