1

I want to define a macro function which support at the same time:

1) No input parameter

2) Input parameters

some thing like that:

#define MACRO_TEST(X)\
    printf("this is a test\n");\
    printf("%d\n",x) // the last printf should not executed if there is no input parameter when calling the macro

In the main:

int main()
{
    MACRO_TEST(); // This should display only the first printf in the macro
    MACRO_TEST(5); // This should display both printf in the macro
}
MOHAMED
  • 41,599
  • 58
  • 163
  • 268

4 Answers4

5

You can use sizeof for this purpose.

Consider something like this:

#define MACRO_TEST(X) { \
  int args[] = {X}; \
  printf("this is a test\n");\
  if(sizeof(args) > 0) \
    printf("%d\n",*args); \
}
geocar
  • 9,085
  • 1
  • 29
  • 37
  • 1
    Oh, I had not thought about a temporary array. That's smart! – cmc Dec 20 '12 at 17:25
  • And please, put it in `do { } while (0)`! – Shahbaz Dec 20 '12 at 17:27
  • Keep in mind that this is not portable. ISO C (e.g.: with `-pedantic` compiler flag) forbids both empty initializer lists and zero-size arrays (both will occur if no argument is passed to the macro), although it is supported by GNU extensions. – netcoder Dec 20 '12 at 18:21
  • I updated your answer in order to support another kind of input behaviour – MOHAMED Dec 21 '12 at 08:50
1

gcc and recent versions of MS compilers support variadic macros - that is macros that work similar to printf.

gcc documentation here: http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html

Microsoft documentation here: http://msdn.microsoft.com/en-us/library/ms177415(v=vs.80).aspx

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
1

Not exactly that but ...

#include <stdio.h>

#define MTEST_
#define MTEST__(x) printf("%d\n",x)
#define MACRO_TEST(x)\
    printf("this is a test\n");\
    MTEST_##x    

int main(void)
{
    MACRO_TEST();
    MACRO_TEST(_(5));
    return 0;
}

EDIT

And if 0 can be used as skip:

#include <stdio.h>

#define MACRO_TEST(x) \
    do { \
        printf("this is a test\n"); \
        if (x +0) printf("%d\n", x +0); \
    } while(0)

int main(void)
{
    MACRO_TEST();
    MACRO_TEST(5);
    return 0;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
0

The C99 standard says,

An identifier currently defined as an object-like macro shall not be redefined by another #define reprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical. Likewise, an identifier currently defined as a function-like macro shall not be redefined by another #define preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.

I think compiler prompts a warning of redefined MACRO. Hence it is not possible.

Sunil Bojanapally
  • 12,528
  • 4
  • 33
  • 46