24

I need to temporarily overwrite a macro and then restore it. Like:

#define FOO X
#save FOO
#define FOO Y
...
#restore FOO

Is it possible in standard C preprocessor? In GCC?

ADDED. About real world example. I use a global macro for error exception. It acts like assert, but for persistent usage, not only for debug versions; so, for example, I usually call functions (with side-effect) inside the macro. It's defined once, but the definition isn't persistent; therefore I don't know it a-priori. For some piece of code I need its own, modified version of the macro, but I want to save general style of code. It's looks ugly when one part of code uses the one macro, other part uses other macro -- both macros have the same purpose, but slightly different implementation.

So, it's good for me to save original macro temporarily, use different version for a part of code, after that restore original macro.

  • Unless you know exactly what `FOO` is before and after, no, this isn't possible. – Richard J. Ross III Jan 10 '13 at 15:42
  • 2
    Why not just change the names of the macros? Seems a lot simpler. – Ed Heal Jan 10 '13 at 15:43
  • 1
    No sure about plain C, but in c++ you can use push_macro: http://stackoverflow.com/questions/1543736/how-do-i-temporarily-disable-a-macro-expansion-in-c-c – Alex G.P. Jan 10 '13 at 15:53
  • @Ed Heal: How? If you mean `#define FOO_SAVED FOO` and then `#define FOO FOO_SAVED` -- it doesn't work, obviously. –  Jan 10 '13 at 16:00
  • You do have control over the source code? notepad++ could change those names – Ed Heal Jan 10 '13 at 16:06
  • 2
    What is actually your use case for this? Can you give a real world example of when this will be useful for you? – slugonamission Jan 10 '13 at 16:55
  • I updated the question for application note. Sorry for bad English please, it's not my native. –  Jan 10 '13 at 19:02
  • @AlexG.P.: `push_macro` is not standard – K-ballo Jan 10 '13 at 19:03
  • @AlexG.P.: Oh, `push_macro` it's seems to be what I search. GCC support it. –  Jan 10 '13 at 19:05
  • @K-ballo: I have asked about GCC extensions too. –  Jan 10 '13 at 19:06
  • @user14284: I know. His comments says _in C++ you can use `push_macro`_, but that's not true; you can only use `push_macro` in _MSVC_ and _GCC_, not in _C++_ – K-ballo Jan 10 '13 at 19:07
  • @K-ballo: I know about standard =) Most of #pragra aren't standard, but it is exists and useful for OP. About terminology... We understood each other. – Alex G.P. Jan 10 '13 at 20:17
  • An instruction like that would be nice to introduce kind-of-a-scope for macros. – milleniumbug Jan 10 '13 at 21:19
  • 1
    Possible duplicate of [Can I redefine a C++ macro then define it back?](https://stackoverflow.com/questions/1793800/can-i-redefine-a-c-macro-then-define-it-back) – pelya Aug 11 '17 at 14:18

3 Answers3

14

This is possible with #pragma push_macro and #pragma pop_macro. These are not standard C—they're originally an MSVC extension—but clang supports them, and so does GCC.

Example usage:

int main() {
#define SOME_MACRO 1
  printf("SOME_MACRO = %d\n", SOME_MACRO);
#pragma push_macro("SOME_MACRO")
#define SOME_MACRO 2
  printf("SOME_MACRO = %d\n", SOME_MACRO);
#pragma pop_macro("SOME_MACRO")
  printf("SOME_MACRO = %d\n", SOME_MACRO);
  return 0;
}

prints:

SOME_MACRO = 1
SOME_MACRO = 2
SOME_MACRO = 1

You can also #undef a macro inside a push_macro / pop_macro pair, and the pop_macro call will redefine it.

nornagon
  • 15,393
  • 18
  • 71
  • 85
  • If the macro did not exist when `push_macro` is called, then `pop_macro` will also undefine it. (at least on MSVC) – Brandlingo Apr 16 '20 at 14:25
  • If the macro is defined before the push_macro pragma is used, it is still defined afterwards, so technically you need to undef the macro before redefining it. Nevertheless I pretty much like this answer. – cardiff space man Jul 16 '20 at 17:04
9

As already said, it is not really possible. Depending on the situation, this might be a workaround:

#include "generalmacrodefs.h" // put them in here or include them indirectly
#undef macro1
#define macro1 "specialized temporary value"
#undef macro1
#include "generalmacrodefs.h" // restores

This requires that generalmacrodefs.h uses a pattern like this at least for the definitions you might temporarily overwrite:

#ifndef macro1
#define macro1 "original value"
#endif
Bernd Elkemann
  • 23,242
  • 4
  • 37
  • 66
1

The closest you can come in C is the #undef directive, which simply undefines the macro, allowing it to be replaced:

#define FOO X

...

#undef FOO
#define FOO Y

...

#undef FOO
#define FOO X

The problem is that you cannot know the 'old' value of FOO once you redefine it - so your values must be hard-coded in one place.

You cannot create a macro to save the values for you either, as it isn't possible to have a macro that creates other preprocessor directives in standard C.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201