Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bypassing a #define'd macro?

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.

like image 889
Vigabrand Avatar asked Jul 22 '14 02:07

Vigabrand


People also ask

What does it mean if you bypass something?

to avoid something by going around it: We took the road that bypasses the town. The oil pipeline bypasses the protected wilderness area.

How do you use bypass in a sentence?

Verb To bypass the city, take the highway that circles it. Is there a way to bypass the bridge construction? He bypassed the manager and talked directly to the owner. She managed to bypass the usual paperwork.

What are bypassing words?

Bypassing is a semantic barrierOpens in new window which occurs when people think they understand each other but actually miss each other's meaning because one or both are using equivocal language—words that can have more than one interpretation.

What is the opposite of bypassing?

Opposite of to avoid or circumvent (a rule, obstacle or problem) follow. keep. meet. obey.


2 Answers

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.

like image 162
jxh Avatar answered Oct 17 '22 00:10

jxh


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.

like image 45
Leushenko Avatar answered Oct 17 '22 00:10

Leushenko