5

Say I have 2 functions

void f1(int p1, int v1, ...);

AND

void f2(int v1, ...);

Inside f1 I want to pass all parameters from variadic list to f2:

void f1(int p1, int v1, ...) {
   f2(/*pass all variadic parameters*/);
}

For example when I call f1(1, 2, 3, 4, 5) I want to pass 2,3,4,5 to f2

3 Answers3

4

Although you already have accepted a correct answer.

An alternative if you don't have access to f2 is to use a variadic macro. This is something that is available since C99:

#define F1(P1, V1, ...)           \
do {                              \
   /* do something with P1, V1 */ \
   f2(__VA_ARGS__);               \
} while(0)

Here the do-while is just a trick to encapsulate your statements such that a call to that macro may appear anywhere a normal statement would and all the \ help to write the macro on several lines.

Such macros are a quite commonly used to augment printf to print log messages with a prefix, e.g:

#define dprintf(...)                               \
do {                                               \
   fprintf(stderr, "%lX: ", (long unsigned)mynum); \
   fprintf(stderr, __VA_ARGS__);                   \
} while(0)
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
3

It's not possible directly, but you can use the va_list type to wrap the full complement of values and pass them to a version of the function that takes such an argument. Basically, break f2() into:

void f2v(int v1, va_list args) {
    // ...
    // use va_arg() repeatedly to get the various arguments here
}

void f2(int v1, ...) {
    va_list args;
    va_start(args, v1);
    f2v(v1, args);
    va_end(args);
}

And then rework f1() to use f2v() instead of f2():

void f1(int p1, int v1, ...) {
    // do whatever else you need to do before the call to f2

    va_list args;
    va_start(args, v1);
    f2v(v1, args);
    va_end(args);

    // do whatever else you need to do after the call to f2
}

This is, in theory, how printf() and vprintf() work--printf() internally can call vprintf() so that two functionally identical implementations are not needed.

(Don't forget--you need to #include <stdarg.h> to get access to va_list, va_start(), etc.)

Jonathan Grynspan
  • 43,286
  • 8
  • 74
  • 104
  • thanks. This is actually situation I was afraid of. Unfortunately I have no access to f2 and can't rewrite it. –  Mar 12 '11 at 15:38
  • Then you can't do it in a portable way in C. If you tell us what `f2()` actually is, we may be able to offer alternatives. – Jonathan Grynspan Mar 12 '11 at 15:39
  • It's a function from an external library (I don't have access to the sources). And I have no alternatives. Thanks anyway. –  Mar 12 '11 at 15:47
  • As long as you don't have to mess with the arguments (i.e. don't have to, say, strip the first argument), you could do this with a bit of assembly that acts as a trampoline. It will be neither straightforward nor non-fragile. – bbum Mar 12 '11 at 21:01
  • Hence why I said "you can't do it in a *portable* way" -- all bets are off when assembly's involved. – Jonathan Grynspan Mar 12 '11 at 23:09
0

In general, you can not do this. However, see this question.

Community
  • 1
  • 1
Massimo Cafaro
  • 25,429
  • 15
  • 79
  • 93