Consider the following setup:
a.h
#define A 5
#define B A
#undef A
#define A 3
a.c
Yes. Boost's preprocessor library (a set of portable includes, not an extended preprocessor) includes support for "mutable" macro definitions. Instead of defining a macro to expand to a value directly, you can define it to expand to a reference a mutable slot, which can be changed because it expands the value "assigned" to it early. In this case you're less interested in the ability to change the value, than in the fact that this early expansion means it can grab the value out of A
at a point ahead of both the use of B
or the redefinition of A
.
#include
#define A 5
#define B BOOST_PP_SLOT(1)
// "assign" A to B
#define BOOST_PP_VALUE A
#include BOOST_PP_ASSIGN_SLOT(1)
#undef A
#define A 3
#include "a.h"
#include
int main()
{
printf("%d\n", B); // 5
return 0;
}
Support is limited to integers. It takes advantage of the fact that #if
directives force expansion of any contained macros (so do #line
and #error
, although those are not very useful for this purpose), and uses them to build up an equivalent integer value for the slot being assigned to, stored in hidden backend macros. This way it can "extract" a value from A
, and B
can then refer to the value itself even if A
changes or is removed.