web-dev-qa-db-fra.com

Quelle est la difference entre exit () et abort ()?

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).

126
Nathan Stoddard

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 de exit(). Le contrôle peut être transféré directement à une telle main() en lançant une exception interceptée dans main().

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.

113

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

32
Brian R. Bondy

Les choses suivantes se produisent lorsqu'un programme appelle exit ():

  • Les fonctions enregistrées par la fonction atexit sont exécutées
  • Tous les flux ouverts sont vidés et fermés, les fichiers créés par tmpfile sont supprimés
  • Le programme se termine avec le code de sortie spécifié vers l'hôte

La 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.

10
Robert Gamble

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.

5
Federico A. Ramponi

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.

4
strager