Preprocesador

El preprocesador Cuando se compila un programa de c++ previamente se hace un preprocesamiento en el que se revisan determinadas variables de preprocesador. Con ellas lo que se consigue es que el compilador modifique el codigo fuente del programa antes de crear el ejecutable. Vamos varios usos utiles.

/**
* Preprocesador.cpp
* Programa c++ que muestra el uso del preprocesador. 
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -o Preprocesador Preprocesador.cpp
*
*/

// include se utiliza para poder utilizar codigo externo,
// generalmente las librerias standar o nuestras propias librerias
using namespace std;
#include <iostream>


// Las variables de preprocesador sirven para que el compilador haga ciertas
// modificaciones en el codigo fuente
#define PI 3.1415

#define BATMAN "Bruce Wayne"

#define MISTERX "Felipe Gonzalez"

#define REVELAR

#define BUFFER 255

// podemos definir FUNCIONES, aunque sin complicarlas ya que dificulta
// la depuracion y se pasa el tipado de variables por el arcoltriunfo
#define PORCENTAJE(a,b) (a*b)/100

// Guardias de inclusion
// Estructura condicional para evitar multiples inclusiones 
// La siguiente structura comprueba si NO se ha definido la variable FSTREAM
#ifndef FSTREAM

// si no se ha definido, la definimos
#define FSTREAM
#include <fstream>
#endif // fin de condicion

// macro de comillas:
#define write(x) cout << #x << endl;


int main () {

	int i = 345;

	float var = 4.67;

	char buffer[BUFFER]; // automaticamente el compilador traduce: buffer[255]

	
	#ifdef PI
		cout << "El valor PI es: " << PI << ": ten fe en el caos" << endl;

	#else
		cout << "PI no esta definido..." << endl;

	#endif

	// ahora miramos una variable de preprocesador que no esta:
	// y asi en este caso no se revelamos quien es BATMAN...

	#ifdef REVELAR
	cout << "Batman realmente se trata de: " << BATMAN << endl;

	#endif
	// con esta orden eliminamos la variable:

	#undef REVELAR

	// y este es el efecto:
	#ifdef REVELAR


	cout << "MisterX realmente es: " << MISTERX << endl;
	
	#endif

	cout << "var * PI = " << (var * PI) << endl;

	// mostramos la llamada a la funcion
	cout << "Porcentaje 15% de "<< i << " es: " << PORCENTAJE(i,15) << endl;

	// llamada a la macro. Atencion, convertira MISTERX?
	write(Hay que ver que lujo verdad MISTERX);

	
	return 0;

}

Macros para depuracion Disponemos de algunas variables de macro que facilitan la depuracion asi como de la funcion assert. Veamos el uso

/**
* Depurador.cpp
* Programa c++ que muestra el uso del preprocesador para depurar
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -o Depurador Depurador.cpp
*
*/

// include se utiliza para poder utilizar codigo externo,
// generalmente las librerias standar o nuestras propias librerias

using namespace std;
#include <iostream>

// Disponemos de estas variables de macro predefinidas, muy utiles para depurar.
// __DATE__ : sustituye esa variable por la fecha 
// __TIME__ : sustituye esa variable por la hora
// __LINE__ : sustituye esa variable por la linea de programa
// __FILE__ : sustituye esa variable por el nombre del fichero del programa

// definimos la variable DEBUG para activar la depuracion
#define DEBUG

// y mostramos el uso de assert(), su disponibilidad dependera del compilador.
// cuando invocamos la funcion assert, si lo que tiene como parametro es TRUE
// no habra problema pero si es false saltara un codigo de depuracion que le digamos
#ifndef DEBUG

#define ASSERT(x)

#else

#define ASSERT(x) \

if (! (x)) { \
cout << "error detectado, fallo: " << #x << "\n"; \
cout << " linea" << __LINE__ << " del fichero " << 
__FILE__ << "\n"; \
}
#endif


// funcion principal para las pruebas:
int main () {

	int i = 345;

	float var = 4.67;
	cout << "hola hoy es: " << __DATE__ << endl;
	
	ASSERT(i>5);
	
	cout << "Este es el fichero: " << __FILE__ << endl;
	cout << "Estamos en la linea: " << __LINE__ << endl; 
	
	ASSERT(i==0);
	

	return 0;

}