Is it possible to fix the base value of one macro when defining another?

Imagine that I want a #define macro to be equal to the current value of another macro (if such a concept exists).

For instance:

 #include "def_a.h" // defines macro A #define BA 

This defines B as A If A later changes the definition (i.e., by redefinition), the value of B also changes (because B expands to A at the point of use, which further expands to the new value of A ).

What I would like is a way to “bake” the value of A in B so that B simply expands to the value of A , not A

For instance:

 #define A first #define B BAKE_IN(A) #undef A #define A second #define C BAKE_IN(A) #undef A #define A third // here I want B to expand to first, and C to expand to second 

Of course, BAKE_IN is not a real thing, but I wonder if there is a way to achieve this effect.

Now I really didn’t say what should happen if A itself is defined in terms of other macros, but I am fine with both “one level of extension” (ie B gets the value A, therefore additional macros are saved), as well as “full expansion "(i.e., A expands completely, recursively, as it would be at the point of use).

+5
source share
2 answers

Macros are never replaced in the body of the #define directive, so there is no way to define a macro as the current value of another macro, except for the limited case of macros whose value is a constant arithmetic expression.

In the latter case, you can use the BOOST_PP_ASSIGN_SLOT from the Boost preprocessor library. (Although most Boost libraries are C ++-specific, the Boost preprocessor library works for both C and C ++ and is independent of any other Boost component.)

+1
source

I do not think there is a clean solution. The closest I found is to store the "strict" values ​​in char arrays:

 #include <stdio.h> #define BAKE_IN(X, id) BAKE_IN_REAL(X ## _, X, id) #define BAKE_IN_REAL(X, Y, id) static const char X ## id[] = #Y; #define BAKE_OUT(X, id) X ## _ ## id #define A first BAKE_IN(A, 1) #define B BAKE_OUT(A, 1) #undef A #define A second BAKE_IN(A, 2) #define C BAKE_OUT(A, 2) #undef A int main(void) { printf("%s\n", B); // prints "first" printf("%s\n", C); // prints "second" return 0; } 

The idea is that the BAKE_IN macro declares an object named like this, for example. A_1 , which contains the current decomposition of A

There are two main limitations:

  • Each pair of BAKE_IN and BAKE_OUT needs a unique identifier
  • Extension is available only in "stiff" form
+1
source

Source: https://habr.com/ru/post/1263927/


All Articles