variable una tipos que programacion objeto matematicas macro ejemplos ejemplo definir define crear constantes constante clases clase c++ c-preprocessor

c++ - una - variables y constantes



¿Hay una manera de hacer un#define dentro de otro#define? (6)

Como complemento de las respuestas anteriores, si realmente desea preprocesar un archivo de origen dos veces, lo cual es casi definitivamente lo que realmente desea hacer, siempre puede invocar su compilador de esta manera:

g++ -E input.cpp | g++ -c -x c++ - -o output.o

Es decir, ejecute el archivo a través del preprocesador, luego ejecute la salida preprocesada a través de una tubería a través de una rutina de compilación completa, que incluye un segundo paso de preprocesamiento. Para que esto tenga una probabilidad razonablemente buena de trabajar, me imagino que tendrías que ser bastante cuidadoso en la forma en que definiste y usaste tus macros, y en general, probablemente no valdría la pena el esfuerzo y el aumento de la generación. hora.

Si realmente desea macros, use soluciones estándar basadas en macros. Si realmente desea una metaprogramación en tiempo de compilación, use plantillas.

En una nota ligeramente relacionada, esto me recuerda el hecho de que el lenguaje de trazado de rayos POV-Ray hizo un uso intensivo de un lenguaje de preprocesamiento bastante complejo, con directivas de control de flujo como #while mientras que permitía la repetición condicional, los cálculos de tiempo de compilación y otros similares. golosinas Ojalá fuera así en C ++, pero simplemente no lo es, así que lo hacemos de otra manera.

Sé que estoy tratando de dispararme en la pierna;) Sin embargo, me permitirá hacer el resto (gran cantidad) del código más pequeño y más legible.

¿Hay alguna manera difícil de crear una macro de preprocesador dentro de otra macro de preprocesador?

Aquí está el ejemplo, lo que estoy buscando. Mi escenario real es más complejo.

// That''s what I want to do and surely C++ doesn''t like it. #define MACROCREATER(B) #define MACRO##B B+B void foo() { MACROCREATOR(5) // This should create new macro (#define MACRO5 5+5) int a = MACRO5; // this will use new macro }


Como se señaló, uno puede #incluir un archivo en particular más de una vez con diferentes definiciones de macro activas. Esto puede hacer que sea práctico lograr algunos efectos que no podrían lograrse en la práctica por otros medios.

Como ejemplo simple, en muchos sistemas integrados, la indirección de punteros es muy costosa en comparación con el acceso directo a variables. El código que utiliza mucha indirección de punteros puede ser dos veces más grande y lento que el código que simplemente usa variables. Por consiguiente, si se usa una rutina en particular con dos conjuntos de variables, en un escenario en el que uno usualmente pasa un puntero a una estructura y luego usa el operador de flecha, puede ser mucho más eficiente poner la rutina en su propio archivo. (Normalmente uso la extensión .i) que está #incluida una vez sin macro _PASS2 definida, y una segunda vez con. Ese archivo puede entonces #ifdef _PASS2 / # else para definir macros para todas las variables que deberían ser diferentes en las dos pasadas. Aunque el código se genere dos veces, en algunos micros tomará menos espacio que usar el operador de flecha con punteros pasados.


Echa un vistazo a m4. Es similar a cpp, pero recursivo y mucho más poderoso. He usado m4 para crear un lenguaje estructurado para ensambladores, por ejemplo,

cmp r0, #0 if(eq) mov r1, #0 else add r1, #1 end

El "if", "else", y "end" son llamadas a las macros m4 que escribí que generan saltos y etiquetas, el resto es ensamblaje nativo. Para anidar estas construcciones if / else / end, debe hacer las definiciones dentro de una macro.


El estándar de C ++ dice (16.3.4.3):

La secuencia de tokens de preprocesamiento [...] de la expansión de macros ... no se procesa por completo y no se procesa como una directiva de preprocesamiento, incluso si se parece a una ...

Así que no, no hay una forma ''oficial'' de lograr lo que quieres con macros.


No. El preprocesador es de una sola pasada. No reevalúa las expansiones macro.

¿Qué te compraría esto, de todos modos? Puede lograr lo mismo que su ejemplo simplemente "insertando" la segunda macro en la primera. p.ej:

#define MACRO(B) B+B void foo() { int a = MACRO(5); }


No. Incluso si una macro se expande en algo que parece una directiva de preprocesamiento, la expansión no se evalúa como una directiva de preprocesamiento.