1.5.1 Funciones de terminación
§1 Sinopsis
C++ dispone en su Librería Estándar de algunas funciones específicamente relacionadas con la terminación del programa y su vuelta al entorno de ejecución. Aunque su descripción correspondería formalmente al capítulo destinado a la Librería Estándar, por la razón ya señalada ( 1.5 [1]) incluiremos aquí una descripción de las mismas.
§2 exit()
Esta función de la Librería Estándar termina la ejecución del programa.
§2.1 Sintaxis
#include <stdlib.h>
void exit(int status);
§2.2 Descripción
la función exit termina el proceso que la ha invocado. Antes de la terminación se cierran todos los ficheros, se escriben los flujos de salida con almacenamiento temporal intermedio (buffer), y son llamadas las funciones de salida que se hayan establecido con la función atexit.
Cuando se invoca exit desde un programa, no son invocados los destructores de ninguna variable local del ámbito actual. Las variables globales son destruidas en su orden normal.
El argumento status
pasado por la función invocante se utiliza como estado de salida del
proceso. La costumbre es que 0 indica terminación normal y un valor
distinto indica algún tipo de error. A este respecto C++ proporciona
algunas constantes predefinidas:
EXIT_FAILURE Terminación anormal, señal al Sistema Operativo que el programa ha terminado con error.
EXIT_SUCCESS Terminación normal.
§2.3 Ejemplo:
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
int main(void) {
int status;
puts("Introducir 1 o 2");
status = getch();
exit(status - '0'); // Sets DOS errorlevel (status - 48)
return
0; //
Observación: esta linea nunca será ejecutada
}
§3 atexit()
Se trata de una función de Librería Estándar <stdlib.h> que cataloga una función como "función de salida" ( 1.5), es decir, la incluye en el lote de las que se ejecutarán justo antes del final de la ejecución.
§3.1 Sintaxis
int atexit(void (_USERENTRY * func)(void));
§3.2 Descripción
El argumento void (_USERENTRY * func)(void)
significa que
atexit debe recibir un
puntero a función func
que no
recibe argumentos y devuelve void. La función debe ser utilizada
siguiendo la convención de llamada _USERENTRY.
Justo antes de la terminación del programa, la función exit
llama la función apuntada por func
y todas las demás que hayan sido registradas como "funciones de
salida", hasta un total de 32, que son ejecutadas como una pila FIFO,
primera en ser registrada primera en ejecutarse.
atexit devuelve un entero: 0 si la operación se realiza correctamente y otro valor si hay error (no existe espacio para registrar la nueva función).
§3.3 Ejemplo
#include <stdio.h>
#include <stdlib.h>
void fun1(void) { puts("Llamada función de salida #1"); }
void fun2(void) { puts("Llamada función de salida #2"); }
int main(void) {
atexit(fun1); // añade fun1 a la
terminacion
atexit(fun2); // añade fun2 a la
terminación
return 0;
}
Salida:
Llamada función de salida #1"
Llamada función de salida #2"
§4 abort()
Esta función de la Librería Estándar <stdlib.h>, provoca la terminación anormal del programa. Téngase en cuenta que abort no destruye las variables globales ni los objetos del ámbito actual en el momento de su invocación.
§4.1 Sintaxis
#include <stdlib.h>
void abort(void);
§4.2 Descripción
Esta función produce una terminación anormal del programa
mediante una llamada a raise(SIGABRT). Si no existe un manejador de
señal para SIGABRT, la función escribe un mensaje de terminación: Abnormal
program termination
en el dispositivo stderr, y termina
la ejecución con una llamada a _exit con un código 3, valor este que
es devuelto al proceso padre o al procesador de comandos del Sistema
Operativo.
§4.3 Ejemplo
#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("El progrma aborta");
abort();
return 0; // Esta línea nunca es ejecutada !!
}
§5 raise()
Esta función de Librería Estándar <signal.h>, es una rutina de control de proceso que envía una señal al programa que lanzó una aplicación. Viene a ser una suerte de manejador de excepciones entre el programa padre y la aplicación lanzada por él.
§5.1 Sintaxis
int raise(int sig);
§5.2 Descripción
Esta función envía una señal sig
al programa padre de la aplicación. Si a su vez el padre ha instalado
un manejador de señal para el tipo especificado por sig
,
se ejecuta este "handler". Si no existe, se ejecuta la acción
prevista por defecto.
Si la operación tiene éxito, la función devuelve 0; en caso contrario un valor distinto.
§5.2.1 El fichero de cabecera signal.h incluye una serie de constantes predefinidas que pueden utilizarse con raise, son las que se indican:
Constante Descripción
SIGABRT Terminación anormal
SIGFPE Operación de coma flotante errónea
SIGILL Instrucción ilegal
SIGINT Interrupción por Ctrl-C
SIGSEGV Acceso a almacenamiento no válido
SIGTERM Petición de terminar el programa
SIGUSR1 Sentido definido por el usuario
SIGUSR2 Sentido definido por el usuario
SIGUSR3 Sentido definido por el usuario
SIGBREAK Interrupción por Ctrl-Break
§5.2.2 Observación
En condiciones normales C++ Builder nunca lanza una llamada raise(SIGABRT),
aunque puede ocurrir en las función abort, y en las excepciones
imprevistas (1.6.3).
Bajo Windows-32 todas las llamadas a raise utilizando estas constantes,
excepto las definidas por el usuario, abortan la ejecución del programa en el
punto de llamada. Por su parte raise(SIGABRT) envía un mensaje
al entorno de ejecución: Abnormal program termination
.
Ejemplo:
#include <signal.h>
int main(void) {
int a = 10, b = 0;
if (b == 0)
raise(SIGFPE); // previene error de dividir por
cero
a = a / b;
return 0;
}