5

Is it possible to add default arguments before variable argument in variadic macro? e.g I have the version of macro something like

#define MACRO(arg1, ...) func(arg1, ##__VA_ARGS__)

I would like to add 2 more default arguments in the macro before variable arguments so that it should not affect previous version. Like:

#define MACRO(arg1, arg2 = "", arg3 = "", ...) func(arg1, arg2, arg3, ##__VA_ARGS__)

Any help would be appreciated.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
vishal
  • 51
  • 1
  • 2
  • 1
    C doesn't support default arguments. Do you mean C++ ? – Paul R Feb 24 '10 at 11:40
  • Not sure In understand, won't
    #define MACRO(arg1, ...) func(arg1, "", "", ##__VA_ARGS__)
    works ?
    – philant Feb 24 '10 at 11:46
  • Yes. Forgot to mention. It's for C++. Thanks – vishal Feb 24 '10 at 11:47
  • Indeed the arguments arg1 and arg2 in func() will be decided based on the values of these arguments in MACRO() inside the source. It can be empty to support backward compatibility. – vishal Feb 24 '10 at 11:59

3 Answers3

5

I do not think this is possible. How would the compiler/preprocessor knows if the second and third arguments are part of the variable arguments or override the default values ? That's the reason why parameters with default values have to be in last position in a function.

I'm afraid you'll have to have two macros or three if you to be able to specify arg2 and use arg3 default value, but this is error-prone.

#define MACRO(arg1, ...) func(arg1, "", "", ##__VA_ARGS__)
#define MACRO2(arg1, arg2, ...) func(arg1, arg2, "", ##__VA_ARGS__)
#define MACRO3(arg1, arg2, arg3, ...) func(arg1, arg2, arg3, ##__VA_ARGS__)
philant
  • 34,748
  • 11
  • 69
  • 112
5

What you can do:

struct foo {
    int   aaa;
    char  bbb;
    char  *ccc;
};

#define BAR(...)   bar((struct foo){__VA_ARGS__})

void bar(struct foo baz)
    /* set defaults */
    if (!baz.aaa)
        baz.aaa = 10;
    if (!baz.bbb)
        baz.bbb = 'z';
    if (!baz.ccc)
        baz.ccc = "default";

    printf("%d, %c, %s\n", baz.aaa, baz.bbb, baz.ccc);
}

...
BAR();                     // prints "10, z, default"
BAR(5);                    // prints "5, z, default"
BAR(5,'b');                // prints "5, b, default"
BAR(5, 'b', "something");  // prints "5, b, something"

Bad thing about this - zero parameter is treated like no parameter, e.g. BAR(0, 'c') will produce string 10, c, default

qrdl
  • 34,062
  • 14
  • 56
  • 86
1

Not as an answer to your question but as a way to simply solve your problem:

#define MACRO(arg1, ...)          \
    /* pre-treatment */           \
    func(arg1, ##__VA_ARGS__)     \
    /* post-treatment */          \

void func (type1 arg1, type2 arg2 = "", type3 arg3 = "", ...);
Rippalka
  • 380
  • 6
  • 16