Reputation: 161
Suppose you have the macro
#define TOKEN1 <arbitrary sequence of characters>
But suppose, in a few cases, you really mean TOKEN1, not what it has been defined to. Is there a trick which allows the pre-processed file to contain "TOKEN1", without #undef'ining TOKEN1, and with TOKEN1 appearing after it has been #define'd?
Context:
I am working on adding memory tracking by redefining new
. But, I am running into the problem that I have also overloaded operator new
in several classes, and it is awkward to have to undefine new in all these places, and then re-include the header that does the magic after.
Upvotes: 6
Views: 687
Reputation: 141648
If you have access to change the definition of TOKEN1 you could make it:
#define TOKEN1() arbitrary stuff...
Then TOKEN1
not followed by (
does not undergo expansion. Even if there is a following (
you can stil suppress it by writing (TOKEN1)
.
Upvotes: 0
Reputation: 70492
A general approach would be to place all code that had the requirement of "do not replace TOKEN1" into a single solitary source file, and then not include the header file that defines the replacement into that file.
If the arbitrary sequence of characters were a single token (as it was before you edited your question), you can do this:
#define TOKEN2 TOKEN1
if (you_really_mean(TOKEN1)) {
//...
}
#undef TOKEN2
But, this solution is limited, since you run into problems if TOKEN2
had already been redefined to something else before.
If you have full control over what is being defined and what not, you can do this:
#define TOKEN1 TOKEN2
#define TOKEN2 <arbitrary sequence formerly assigned to TOKEN1>
Then, in your code to escape TOKEN1
:
#undef TOKEN1
//... code where you don't want TOKEN1 replaced
#define TOKEN1 TOKEN2
For your particular problem for handling overloaded new
, I find that largely, overloaded new
implementations are mostly identical (because they are usually just boiler plate code changing the allocator to use something other than system heap). If this is the case for you as well, you can put the overload definitions into an unguarded header file. This header file can #undef
the definition of new
and then redefine it again after the overload definitions.
Then any class can include this header file.
Upvotes: 3
Reputation: 13370
There's a GCC/Clang extension that can do something like this (I think MSVC has a similar one too), if you have access to language extensions:
#define TOKEN1 123
#pragma push_macro("TOKEN1")
#undef TOKEN1
TOKEN1 // inserts TOKEN1 into the program text
#pragma pop_macro("TOKEN1")
TOKEN1 // inserts 123 into the program source text
It allows you to save and restore macro definitions independently of the input text, for just such a purpose.
jxh's solution is cleaner, though; but fundamentally, you should be rethinking whatever your reasons are for trying to make a single term have multiple meanings. The macro language is supposed to help you abstract elements of a single, unified program; not create two competing, fighting sources in one file.
Upvotes: 3
Reputation: 137930
You can temporarily bypass the definition by adding the "reverse" macro, if <arbitrary sequence of characters>
is valid as a macro invocation (it has the form of an identifier or id( args )
).
#define TOKEN1 arbitrary_identifier
TOKEN1 // expands to arbitrary_identifier
...
// Now we really want to say TOKEN1
#define arbitrary_identifier TOKEN1
TOKEN1 // TOKEN1 => arbitrary_identifier => TOKEN1 and stop expanding
// Finished with TOKEN1 override
#undef arbitrary_identifier
TOKEN1 // expands to arbitrary_identifier again.
I don't think a workaround exists for a truly arbitrary sequence of expansion tokens. And, this workaround is really no better than #undef TOKEN1
and then doing #define
again, since the bypass code still needs to know the expansion.
Upvotes: 0