1

I want to pass a va_list through to another function. Here is an example of what i am trying to do:

void my_printf_1(char* string, ...) {
    va_list ap;
    va_start(ap, string);
    printf(string, ap);
    va_end(ap);
}

void my_printf_2(char* string, ...) {
    va_list ap;
    va_start(ap, string);
    printf(string, *ap);
    va_end(ap);
}

int main(void) {
    my_printf_1("Hello %i\n", 12); //Shows me the pointer
    my_printf_1("Hello \n"); //Runtime Error - too many arguments
    my_printf_2("Hello %i\n", 12); //Displays correctly because 12 < char
    my_printf_2("Hello %i\n", 500); //Displays incorrectly  because 500 > char
    my_printf_2("Hello %i %i\n", 12, 12); //Displays 12, then crashes Runtime Error not enough arguments
    my_printf_2("Hello \n"); //Runtime Error - too Many Arguments
}

It seems to me that my va_list ap is a char pointer, how can i get the whole List? How can i rewrite my_printf() to pass the whole or a fake va_list to subfunctions? I can not modify my subfunctions to accept va_list pointers, so i will have to modify my_printf.

EDIT: I realize that the following would work, however this is not what i want.

void my_printf_1(char* string, ...) {
    va_list ap;
    va_start (ap, string);
    vprintf(string, ap);
    va_end(ap);
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Johannes
  • 6,490
  • 10
  • 59
  • 108
  • Your compiler+headers may happen to define `va_list` as `char*`, but that is implementation dependent. You can only operate on a `va_list` with `va_start`, `va_arg`, `va_copy` and `va_end`, as described in e.g. C99 standard 7.15. – PJTraill Aug 25 '15 at 14:50

2 Answers2

6

You need to do what you say, but explicitly. That is, pass the actual va_list object.

See the vsnprintf() function for inspiration. Functions that take an explicit va_list are often prefixed with a v in the standard library.

The va_list doesn't have an internal structure that you can work with, it's opaque. All you can do is defined in the <stdarg.h> header.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • i should have been more explicit, i basically want to mock a real va_list. – Johannes Apr 28 '11 at 12:31
  • Aside from this, it is not possible. You cannot pass the arguments onto another variadic function with C. – R.. GitHub STOP HELPING ICE Apr 28 '11 at 12:37
  • Can i create a fake one and cast it into the right format? E.g. via an array or a struct? – Johannes Apr 28 '11 at 12:44
  • `va_list` is not opaque: it's even documented in the SystemV ABI and it's not opaque because you can change the fields. I did it here: https://gitlab.com/eric.saintetienne/revstr#using-vsscanf It's not portable of course as with anything ABI related. – Eric Jan 24 '22 at 22:27
1

Check out vprintf and friends. http://www.manpagez.com/man/3/vprintf/

Richard Pennington
  • 19,673
  • 4
  • 43
  • 72