script c++ c error-handling exit abort

c++ - script - ¿Cuál es la diferencia entre exit() y abort()?



exit status 2 (5)

Desde la página de manual de exit ():

La función exit () causa la terminación normal del proceso y el valor del estado & 0377 se devuelve al padre.

Desde la página de manual de abort ():

El abort () aborta primero la señal SIGABRT, y luego levanta esa señal para el proceso de llamada. Esto da como resultado la finalización anormal del proceso a menos que se capte la señal SIGABRT y el manejador de señales no regrese.

En C y C ++, ¿cuál es la diferencia entre exit() y abort() ? Estoy tratando de finalizar mi programa después de un error (no una excepción).


Las siguientes cosas suceden cuando un programa llama a exit ():

  • Las funciones registradas por la función atexit se ejecutan
  • Todas las transmisiones abiertas se vacían y se cierran, los archivos creados por tmpfile se eliminan
  • El programa finaliza con el código de salida especificado para el host

La función abort () envía la señal SIGABRT al proceso actual; si no se captura, el programa finaliza sin garantía de que las corrientes abiertas se vacíen / cierren o que los archivos temporales creados mediante tmpfile se eliminen, no se atexit las funciones registradas de atexit , y un estado de salida distinto de cero se devuelve al host.


abort() sale de su programa sin llamar a funciones registradas usando atexit() primero, y sin llamar primero a los destructores de objetos. exit() hace ambas cosas antes de salir de tu programa. Sin embargo, no llama destructores para objetos automáticos. Asi que

A a; void test() { static A b; A c; exit(0); }

Destruirá a y b correctamente, pero no llamará a destructores de c . abort() no invocaría destructores de ninguno de los objetos. Como esto es desafortunado, el Estándar C ++ describe un mecanismo alternativo que asegura la terminación adecuada:

Los objetos con duración de almacenamiento automática se destruyen en un programa cuya función main() no contiene objetos automáticos y ejecuta la llamada a exit() . El control se puede transferir directamente a tal main() lanzando una excepción que se captura en 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); } }

En lugar de llamar a exit() , arregle ese código throw exit_exception(exit_code); en lugar.


abort envía la señal SIGABRT . abort no regresa a la persona que llama. El controlador predeterminado para la señal SIGABRT cierra la aplicación. stdio file streams se stdio , luego se cierra. Sin embargo, los destructores para instancias de clase C ++ no lo son (no estoy seguro de esto, ¿quizás los resultados no están definidos?).

exit tiene sus propias devoluciones de llamada, establecidas con atexit . Si se especifican las devoluciones de llamada (o solo una), se llaman en el orden inverso de su orden de registro (como una pila), y luego sale el programa. Al igual que con abort , la exit no regresa a la persona que llama. stdio file streams se stdio , luego se cierra. Además, se invocan destructores para instancias de clase C ++.


abort envía una señal SIGABRT, exit solo cierra la aplicación realizando la limpieza normal.

Puede manejar una señal de cancelación como lo desee, pero el comportamiento predeterminado es cerrar también la aplicación con un código de error.

abort no realizará la destrucción de objetos de sus miembros estáticos y globales, pero saldrá de la voluntad.

Por supuesto, sin embargo, cuando la aplicación está completamente cerrada, el sistema operativo liberará cualquier memoria no liberada y otros recursos.

Tanto en el aborto como en la finalización del programa de salida (suponiendo que no haya anulado el comportamiento predeterminado), el código de retorno se devolverá al proceso principal que inició su aplicación.

Vea el siguiente ejemplo:

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; }

Comentarios:

  • Si no se cancela el aborto : no se imprime nada y no se llamará al destructor de algún objeto.

  • Si se comenta el aborto como se indicó anteriormente: se llamará a algún destructor de objetos, obtendrá el siguiente resultado:

función de salida 2
función de salida 1