19

I have the following function:

void doStuff(int unusedParameter, ...)
{
    va_list params;
    va_start(params, unusedParameter);
    /* ... */
    va_end(params);
}

As part of a refactor, I'd like to remove the unused parameter without otherwise changing the implementation of the function. As far as I can tell, it's impossible to use va_start when you don't have a last non-variadic parameter to refer to. Is there any way around this?

Background: It is in fact a C++ program, so I could use some operator-overloading magic as suggested here, but I was hoping not to have to change the interface at this point.

The existing function does its work by requiring that the variable argument list be null-terminated, and scanning for the NULL, therefore it doesn't need a leading argument to tell it how many arguments it has.

In response to comments: I don't have to remove the unused parameter, but I'd do it if there were a clean way to do so. I was hoping there'd be something simple I'd missed.

Community
  • 1
  • 1
Tim Martin
  • 3,618
  • 6
  • 32
  • 43
  • look @ http://stackoverflow.com/questions/1436968/variadic-function-without-specified-first-parameter – Axarydax Apr 12 '10 at 13:02
  • @Axarydax: He specifically asks if there is another solution. – Aaron Digulla Apr 12 '10 at 13:05
  • 6
    do you really have to remove it? You can treat it as the 1st variadic parameter. – Nick Dandoulakis Apr 12 '10 at 13:11
  • @Nick D: You should make your comment an answer, you'd get at least one upvote from me. – mouviciel Apr 12 '10 at 13:32
  • "scanning for the NULL" - and you say you *don't* want to change the interface? For instance, to pass a pointer to an array ;-) – Steve Jessop Apr 12 '10 at 17:31
  • Of course, I'll change the interface entirely in due course. I find refactoring works best as a bunch of small testable steps (in this case, turning a non-member function into a member function) rather than trying to rewrite the code all at once. – Tim Martin Apr 14 '10 at 08:41
  • Another [good example to make what you want](https://stackoverflow.com/a/23647983/7104681). – Dennis V Jun 21 '17 at 11:51
  • Another [good example to make what you want](https://stackoverflow.com/a/30199332/7104681) – Dennis V Jun 21 '17 at 11:54

2 Answers2

16

In GCC, you have a workaround: You can define a macro with a variable number of arguments and then add the dummy parameter in the expansion:

#define doStuff(...) realDoStuff(0, __VA_ARGS__)
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
3

Your choice is either leave it as it is and use va_list, alias it (if it's GCC) as others pointed out, or do something along the lines of exec(2) interface - passing an array of pointers requiring a NULL terminator:

/* \param args  NULL-terminated array of
 *              pointers to arguments.
 */
void doStuff( void* args[] );

Either way it would be much better to refactor the interface to somehow take advantage of the type system - maybe overload on exact argument types used:

void doStuff( int );
void doStuff( const std::string& );
void doStuff( const MyFancyAppClass& );

Hope this helps.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171