13

Suppose I have the following macro:

#define xxx(x) printf("%s\n",x);

Now in certain files I want to use an "enhanced" version of this macro without changing its name. The new version explores the functionality of the original version and does some more work.

#define xxx(x) do { xxx(x); yyy(x); } while(0)

This of course gives me redefition warning but why I get 'xxx' was not declared in this scope? How should I define it properly?

EDIT: according to this http://gcc.gnu.org/onlinedocs/gcc-3.3.6/cpp/Self_002dReferential-Macros.html it should be possible

Brian Tompsett - 汤莱恩
  • 5,438
  • 68
  • 55
  • 126
jackhab
  • 16,214
  • 34
  • 96
  • 132
  • 1
    That self-referential macros page is describing the rules preventing infinite recursion of macro replacement. It doesn't mean that you can define a macro to mean more than one thing. – James McNellis Jun 21 '10 at 13:44

6 Answers6

6

Not possible. Macros can use other macros but they are using the definition available at expand time, not definition time. And macros in C and C++ can't be recursive, so the xxx in your new macro isn't expanded and is considered as a function.

AProgrammer
  • 49,582
  • 8
  • 87
  • 140
4

You won't be able to reuse the old definition of the macro, but you can undefine it and make the new definition. Hopefully it isn't too complicated to copy and paste.

#ifdef xxx
#undef xxx
#endif
#define xxx(x) printf("%s\n",x);

My recommendation is defining an xxx2 macro.

#define xxx2(x) do { xxx(x); yyy(x); } while(0);
Mike
  • 655
  • 2
  • 7
  • 21
  • 3
    Note that the `#ifdef` block is not needed. You can use `#undef` on a name to undefine it as a macro, even if that name isn't currently defined as a macro. So, you can simply `#undef xxx` and then `#define xxx...`. – James McNellis Jun 21 '10 at 13:46
  • Cool! Didn't know about that. Leaving off the `#ifdef` makes the code more readable. – Mike Jun 21 '10 at 13:52
  • I have a Project-Prefix.pch where I set defaults that are common for app of my apps and then have app specific Prefix.pch's for things that change. I was getting an warning 'Lexical or Preprocessor Issue macro redefined' when I redefined a macro and couldn't figure out how to turn that warning off in the pre-processor. #undef PLAY_BUTTON_TITLE and then #define PLAY_BUTTON_TITLE @"Start" suppresses the error and redefines the button. – JScarry May 08 '13 at 16:18
3

If we know type of 'x' parameter in the 'xxx' macro, we can redefine macro by using it in a function and then define the 'xxx' macro as this function

Original definition for the 'xxx' macro:

#define xxx(x) printf("xxx %s\n",x);

In a certain file make enhanced version of the 'xxx' macro:

/* before redefining the "xxx" macro use it in function 
 * that will have enhanced version for "xxx" 
 */
static inline void __body_xxx(const char *x)
{
    xxx(x);
    printf("enhanced version\n");
}

#undef  xxx
#define xxx(x) __body_xxx(x)
snv.dev
  • 101
  • 1
  • 2
3

Self-referential macros do not work at all:

http://gcc.gnu.org/onlinedocs/cpp/Self_002dReferential-Macros.html#Self_002dReferential-Macros

If you're working on C++ you can obtain the same results with template functions and namespaces:

template <typename T> void xxx( x ) {
        printf( "%s\n", x );
}

namespace my_namespace {

template <typename T> void xxx( T x ) {
        ::xxx(x);
        ::yyy(x);
}

}
Miquel Ramirez
  • 523
  • 2
  • 6
1

From: https://gcc.gnu.org/onlinedocs/gcc/Push_002fPop-Macro-Pragmas.html

#define X  1
#pragma push_macro("X")
#undef X
#define X -1
#pragma pop_macro("X")
int x [X];
0

It is not exactly what you're asking for but it can help.

You can #undef a macro prior to giving it a new definition.

Example:

#ifdef xxx
#undef xxx
#endif
#define xxx(x) whatever

I never heard of (or seen) a recursive macro though. I don't think it is possible.

ereOn
  • 50,978
  • 36
  • 154
  • 231
  • 2
    Note that the `#ifdef` block is not needed. You can use `#undef` on a name to undefine it as a macro, even if that name isn't currently defined as a macro. So, you can simply `#undef xxx` and then `#define xxx...`. – James McNellis Jun 21 '10 at 13:42
  • @James McNellis: Good to know. Thanks! – ereOn Jun 21 '10 at 15:30