Disponible la nueva versión "donationware" 7.3 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


1.5  Secuencia de ejecución de un programa


Desde que es invocado por su entorno (normalmente el Sistema Operativo) hasta que termina, la ejecución de un programa C++ recorre las siguientes etapas:


§1
  Se ejecuta el módulo inicial.

Durante la fase de enlazado de la compilación, el enlazador añade a cualquier programa C++ un módulo especial, de inicio, que es realmente el punto de entrada a la ejecución del programa [2]. Este módulo realiza diversas tareas, entre ellas iniciar todas las variables estáticas o globales (ver nota), controlar la ejecución de posibles funciones opcionales de inicio (ver punto siguiente) y finalmente, invocar la función main ( 4.4.4).

Nota: cuando se compila cualquier módulo, en el objeto resultante existe un segmento denominado _INIT_ que contiene una referencia ("Init entry") al constructor de cada objeto global que deba ser inicializado, así como un orden de prioridad.  Más tarde, cuando el enlazador construye un ejecutable, estas entradas se agrupan en una tabla, la tabla de inicio ("Init table") que contiene ordenadamente todas las entradas de los constructores de los objetos que existen en los módulos que componen el programa.  Finalmente, esta tabla es utilizada por el módulo de inicio cuando el programa es iniciado.


§2
  Se ejecutan las funciones de inicio.

Algunos compiladores permiten al programador la opción de que se invoquen determinadas funciones, antes que se realice la llamada a main. Estas funciones representan tareas preparatorias adicionales, que queremos realizar antes de que se inicie la ejecución. Esto se consigue con la directiva de inicio #pragma startup ( 4.9.10i).


§3
  Se invoca la función main()

Después de lo anterior, el control pasa a una función que debe responder al nombre de main y le pasa algunos argumentos en base a datos que ha recibido a su vez del Sistema Operativo ( 4.4.4).  Así pues, en ausencia de funciones particulares de inicio, main representa el punto de la ejecución a partir del cual el programador toma control de la ejecución. El cuerpo de esta función representa la ejecución del programa, su "carga útil".


§4
  Se ejecutan las funciones de salida.

Algunos compiladores permiten la opción de llamar determinadas funciones antes que se alcance el final del programa, justo antes de su terminación. Estas funciones, que representan tareas adicionales que queremos realizar antes de que el programa devuelva el control a su entorno de ejecución. Se establecen con la directiva  #pragma exit  ( 4.9.10i).

La Librería Estándar C++ también proporciona una función especial: atexit() que permite la opción de ejecutar un código específico en la terminación ( 1.5.1).

§5  Finalización

Un programa C++ puede terminar por varios motivos:

  • Se termine la función main(). Bien porque se alcance el corchete de cierre "}", bien porque se encuentra una sentencia return;  esto último es lo deseable (aunque no imprescindible), ya que el estándar define que main debe devolver un int a su entorno de ejecución ( 4.4.4).
  • Se encuentra una invocación a la función exit(), una función de la Librería Estándar ( 1.5.1).
  • Se encuentra una invocación a la función abort(), otra función Librería Estándar ( 1.5.1).
  • Se lanza una excepción que no encuentra su manejador ("handler") correspondiente ( 1.6.3 Excepciones imprevistas).

  En el apartado 1.5.1 se incluye la descripción de algunas de las funciones relativas a la terminación de un programa [1].

Hay que recordar que en un programa C++ todos los objetos globales se mantienen activos hasta que se han ejecutado todas las funciones de salida. Las variables locales, incluyendo las declaradas en la función main son destruidas a medida que quedan fuera de ámbito. Al final de un programa C++ Builder el orden de ejecución es como sigue:

  • Las funciones de salida son ejecutadas en el mismo orden que fueron insertadas por atexit.
  • Las funciones declaradas en #pragma exit son ejecutadas en orden a sus códigos de prioridad.
  • Se llama al destructor de variables globales.


  Ver algunos comentarios adicionales sobre un caso concreto: 2.2.6.

  Inicio.


[1]  Aunque en rigor su descripción debería estar incluida en el capítulo 5 dedicado a la Librería Estándar, mientras no implemente completamente dicha parte en el presente "Libro", mantendremos aquí la descripción de estas funciones.

[2]  El Estándar indica que tanto este módulo como el de terminación son dependientes de la implementación (pueden ser diferentes para cada compilador).