How to rename a C preprocessor macro?
Not with the pre-processor, at least, not that I am aware of.
However, for simple constants with known type like in your example, there is a workaround.
#include <stdio.h>
// <xyz.h>
#define XYZ 42
// </xyz.h>
enum xyz_constants
{
LIB_XYZ = XYZ,
};
#undef XYZ
#define XYZ 27
int
main()
{
printf("old value: %d, new value: %d\n", LIB_XYZ, XYZ);
return 0;
}
Not showing the fluff from stdio.h
, this code is pre-processed to the following.
enum xyz_constants
{
LIB_XYZ = 42,
};
int
main()
{
printf("old value: %d, new value: %d\n", LIB_XYZ, 27);
return 0;
}
You can extend this to some degree to other data types and certain function-like macros but there are of course limits.
Anyway, why do you need the particular identifier XYZ
? Can't you use a different name for your macro?
If XYZ
from lib.h
is a number [or a constant of a variety], you could use an enum
:
enum { LIB_XYZ = XYZ };
#undef XYZ
If XYZ
is not the above, you have to create (e.g.) myxyz.c
that does not include lib.h
and use XYZ
there (other files may include xyz.h
)
The difference is that #define LIB_XYZ XYZ
will not be resolved at that line, only when you use it later, as in:
foo(LIB_XYZ);
so that won't work because you've already #undef'ed
the XYZ
.
A preprocessor symbol is a name. There is no preprocessing directive which changes the name itself, while preserving the contents. For instance, given either:
#define FOO 42
or
#define FOO(x, y) x ## y (
There is no way to define a macro called BAR
which has the same contents, without repeating these definitions. That is to say, there is no operation like:
#alias BAR FOO // nonexistent fantasy macro-cloning preprocessor directive
Nor like this:
#rename BAR FOO // like #alias BAR FOO followed by #undef FOO
If we do this:
#define BAR FOO // for the #define FOO 42 case
it's not an alias. Macro BAR
is defined such that its replacement token sequence is the token FOO
, and not 42
. If the FOO
macro disappears, then BAR
loses its meaning.
Note also that C preprocessor macros cannot expand into preprocessing directives, so the following approach also will not work:
// wrong:
#define MACRO_DEFINER(NAME) \
#define NAME 42
MACRO_DEFINER(FOO) // hoping for #define FOO 42: no such luck
MACRO_DEFINER(BAR) // hoping for #define BAR 42: likewise
I'm afraid that you have to take a few steps back to find an alternative strategy to whatever problem you're trying to solve. If you get stuck, create a new question about the actual problem.
There is always code generation: generating C or C++ at build time. Then any textual substitution or expansion you can dream of is possible, if you just tweak your generation system.
Any solution that involves #undef XYZ
risks brekaing the functionality of the library header. The library might do something like this:
#define XYZ 42 #define macro(B) bloop(XYZ, B)
If we are using macro
, then we break it if we redefine XYZ
.
If the library is known for defining XYZ
and we manage to redefine it successfully in code which uses that library, the situation will be confusing to future maintainers. "Oh, this XYZ
is not actually that library one; this programmer just wanted an unrelated XYZ
."
The best solution here is to stop wanting to use XYZ
and find some other name. Adapt to the libraries you're using; don't clash with them.