que programa preprocesamiento preprocesador informatica funcion estructura ejemplos directivas c++ c-preprocessor

programa - funcion preprocesador en c++



¿Por qué debería uno molestarse con las directivas de preprocesador? (13)

Esta pregunta puede parecer bastante básica, pero proveniente de una formación en ingeniería (no informática), no estaba seguro de cuáles eran los fragmentos de '' # '' s en algún código C ++.

Una búsqueda rápida me llevó a la concisa y bien explicada página de tutoriales de cplusplus sobre directivas de preprocesador.

Pero ¿por qué molestarse con el concepto de directivas de preprocesador? ¿No es posible escribir código equivalente que pueda asignar valores a constantes, definir subrutinas / función / macros y manejar errores?

Supongo que, en última instancia, quiero saber cuándo es una buena práctica usar tales directivas de preprocesador y cuándo no.


Pero ¿por qué molestarse con el concepto de directivas de preprocesador? ¿No es posible escribir código equivalente que pueda asignar valores a constantes, definir subrutinas / función / macros y manejar errores?

Su uso es muy bajo en C ++, se crearon características del lenguaje para evitar problemas asociados con el preprocesador.

Supongo que, en última instancia, quiero saber cuándo es una buena práctica usar tales directivas de preprocesador y cuándo no.

En general, las fuentes de C ++, a menudo se consideran una mala práctica, especialmente cuando existe un medio para hacerlo utilizando otras características del lenguaje. Se requiere para algunas cosas (es decir, programas dependientes de la plataforma / construcción y programas generativos). En resumen, generalmente hay un reemplazo que se adapta bien. (como la definición constante como enumeración, o plantillas en línea en lugar de macros). Si se encuentra usando uno y no está seguro, solo pregunte / busque si hay una mejor manera de declarar this_code_snippet en C ++, sin el preprocesador.


Debido a que las directivas de preprocesador se ejecutan en tiempo de compilación , mientras que el código que usted escribe se ejecutará en tiempo de ejecución . Por lo tanto, las directivas de preprocesador le brindan la posibilidad de modificar su código fuente mediante programación.

Tenga en cuenta que el preprocesador de C es un mecanismo bastante tosco para este tipo de cosas; El sistema de plantillas de C ++ proporciona un marco mucho más poderoso para la construcción de código en tiempo de compilación. Otros idiomas tienen funciones de metaprogramación aún más potentes (por ejemplo, el sistema macro de Lisp).


El preprocesador de C realiza varias tareas, algunas de las cuales, pero no todas, tienen mejores alternativas en C ++. Donde C ++ tiene una mejor alternativa, úsala. Esas alternativas incluyen plantillas, inlineado y variables const (un oxímoron, pero eso es lo que el estándar las llama) en lugar de las macros #define.

Sin embargo, hay pocas cosas que no querría prescindir o simplemente no puede prescindir; #include por ejemplo es esencial, y cuando se codifica para múltiples plataformas o configuraciones, la compilación condicional sigue siendo útil (aunque debe usarse con moderación en todos los casos).

Las extensiones específicas del compilador controladas a través de #pragma pueden ser inevitables en algunos casos.


El preprocesamiento se produce antes de compilar el código. Es apropiado en casos como los siguientes

#ifdef WIN32 #include <something.h> #elseif LINUX #include <somethingelse.h> #endif

Obviamente, incluyendo los archivos de encabezado que desea hacer en tiempo de compilación no en tiempo de ejecución. No podemos hacer esto con variables.

Por otra parte. Con C ++ es una buena práctica y se recomienda encarecidamente reemplazar expresiones constantes como el siguiente ejemplo

#define PI 3.141592654 with const double PI=3.141592654;

La razón es que se obtiene una conversión de caracteres adecuada y el manejo de tipos de datos.

también

#define MAX(x,y) (x) > (y) ? (x) : (y)

No es muy agradable porque puedes escribir.

int i = 5 int max = MAX(i++, 6);

El preprocesador reemplazaría eso con:

int max = (i++) > (6) ? (i++) : (6);

Lo que claramente no va a dar el resultado previsto.

En su lugar, MAX debería ser una función (no una macro). Si es una función, también puede proporcionar el tipo en el parámetro.

He visto el preprocesador usado para todo tipo de cosas interesantes. Como declaración de palabras clave de idioma. Puede ayudar en la legibilidad en este caso.

En resumen, use el preprocesador para las cosas que deben suceder en el tipo de compilación, como las directivas de inclusión condicional. Evita usarlo por constantes. Evita las macros y en su lugar usa funciones cuando sea posible.


En general, las directivas de preprocesador no deben utilizarse. Lamentablemente, a veces hay que hacerlo en C y C ++.

C originalmente definió el lenguaje de tal manera que realmente no podía hacer nada serio con él sin usar el preprocesador. El lenguaje no tenía otro soporte incorporado para crear programas modulares, constantes, código en línea o para hacer programación genérica.

C ++ se deshace de la mayoría de estos problemas, pero la instalación aún está allí, por lo que aún se usa. (Curiosamente, no la modularización. Todavía estamos atascados con #include ),

Si desea comparar con un lenguaje creado en un nivel similar de abstracción para tareas similares que no tiene un preprocesador, vaya a Ada .


Es un sustituto mejor que nada para obtener algunas capacidades de reflexión de C ++.

Muy útil para generar variables y cadenas con los mismos nombres.


Muchos lenguajes de programación tienen facilidades de meta-programación , donde se escribe el código para que el compilador lo siga, en lugar del entorno de ejecución.

Por ejemplo, en C ++, tenemos plantillas que nos permiten indicar al compilador que genere cierto código basado en un tipo, o incluso una constante de tiempo de compilación. Lisp es quizás el ejemplo más famoso de un lenguaje con instalaciones avanzadas de meta-programación.

Las directivas / macros de preprocesador de C son solo otra forma de "meta-programación", aunque es una forma relativamente más burda de la que está disponible en otros idiomas. Las directivas de preprocesador le indican al compilador que haga ciertas cosas en el momento de la compilación, como ignorar cierto código en ciertas plataformas, o buscar y reemplazar una cadena en el código con otra cadena. Esto sería imposible de hacer en tiempo de ejecución, después de que su código ya esté compilado.

Esencialmente, el preprocesador C es una forma temprana de "meta-programación", o compilación-programación.


No, en realidad no es posible sobrevivir sin el preprocesador en todos los casos. Una de mis macros favoritas es

#define IFDEBUG if(DEBUG==1) //usage: IFDEBUG{ printf("Dump of stuff:.,,,"); }else{ //..do release stuff }

Sin macros, habría perdido (posiblemente mucho) espacio en el ejecutable final

Y también debe darse cuenta de que C / C ++ no tiene ningún tipo de paquete que require u otro sistema similar. Por lo tanto, sin el preprocesador, no hay forma de evitar la duplicación de código. (los archivos de cabecera no pueden ser incluidos)



Respuesta 1: código condicional que debe variar según el tipo de computadora en la que funciona.

Respuesta 2: habilitar y deshabilitar las extensiones de idioma y las características de compatibilidad que se ven en el momento de la compilación.

El preprocesador vino de C, donde había muchas cosas que no podía expresar. El buen código C ++ encuentra menos razones para usarlo que el código C, pero lamentablemente no es del todo inútil.


Se usa con más frecuencia para dos cosas que serán más difíciles de organizar sin él:

  1. Incluir guardias .
  2. Diferentes secciones de código para diferentes plataformas.

Un poco de historia aquí: C ++ se desarrolló a partir de C, que necesitaba el preprocesador mucho más que C ++. Por ejemplo, para definir una constante en C ++, escribirías algo como const int foo = 4; , por ejemplo, en lugar de #define FOO 4 que es el equivalente en C aproximado. Desafortunadamente, demasiadas personas trajeron sus hábitos de preprocesador de C a C ++.

Hay varios usos razonables del preprocesador en C ++. El uso de #include para los archivos de cabecera es bastante necesario. También es útil para la compilación condicional, incluyendo guardias de inclusión de encabezado, por lo que es posible #include incluir un encabezado varias veces (como en encabezados diferentes) y procesarlo solo una vez. La declaración de afirmación es en realidad una macro de preprocesador, y hay algunos usos similares.

Aparte de estos, hay muy pocos usos legítimos en C ++.


Utiliza directivas de preprocesador cuando necesita hacer algo fuera del alcance de la aplicación real. Por ejemplo, verá que se realiza el preprocesamiento para incluir o no el código basado en la arquitectura para la que se está construyendo el ejecutable. Por ejemplo:

#ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers #include <windows.h> #else #include <unistd.h> #endif

Las directivas de preprocesador también se utilizan para guardar las inclusiones, de modo que las clases / funciones, etc., no se definan más de una vez.

#ifndef MY_CLASS_6C1147A1_BE88_46d8_A713_64973C9A2DB7_H_ #define MY_CLASS_6C1147A1_BE88_46d8_A713_64973C9A2DB7_H_ class MyClass { .... }; #endif

Otro uso es para incrustar versiones dentro de código y bibliotecas.

En el Makefile tienes algo como:

-D MY_APP_VERSION=4.5.1

Mientras que en el código tienes

cout << "My application name version: " << MY_APP_VERSION << endl;