va_list passthrough

R

raphfrk

Is there any way to pass a variable list to a function, so as to act
as a passthrough?

for example:

void new_printf ( char *buf , ... )
{
va_list vlist;

<modify buf slightly>

printf( buf , vlist );
}
 
S

santosh

raphfrk said:
Is there any way to pass a variable list to a function, so as to act
as a passthrough?

for example:

void new_printf ( char *buf , ... )
{
va_list vlist;

<modify buf slightly>

printf( buf , vlist );
}

Use va_copy.
 
R

raphfrk

Use va_copy.


I don't think that is what I want.

I want a program that would allow something like the following to
work.

#include <stdio.h>

int main()
{

int a=7l;

new_printf("%d\n" , a );

return 0;
}

void new_printf ( char *buf , ... )
{

printf( buf , ... ); // the va list is passed to printf

}

The effect of the above would be that new_printf acts the same as
printf.
 
R

rahul

Is there any way to pass a variable list to a function, so as to act
as a passthrough?

for example:

void new_printf ( char *buf , ... )
{
  va_list vlist;

  <modify buf slightly>

  printf( buf , vlist );

}

Use va_copy.
#include <stdarg.h>
void va_copy(va_list dest, va_list src);

The prototype is self explanatory. How do you plan to modify va_list?
 
R

raphfrk

Use va_copy.
#include <stdarg.h>
void va_copy(va_list dest, va_list src);

The prototype is self explanatory. How do you plan to modify va_list?


I don't, I want to pass the va_list to the printf function (any
modifications would be to the buf field).
 
K

Kenny McCormack

Use va_copy.
#include <stdarg.h>
void va_copy(va_list dest, va_list src);

The prototype is self explanatory. How do you plan to modify va_list?


I don't, I want to pass the va_list to the printf function (any
modifications would be to the buf field).[/QUOTE]

For some reason, nobody here wants to tell you about the vprintf() function.

This is in line with official, stated, CLC policy - which is to never
give a sucker an even break.
 
B

Ben Bacarisse

Only if it accepts a va_list.
I don't think that is what I want.

I want a program that would allow something like the following to
work.

#include <stdio.h>

int main()
{

int a=7l;

new_printf("%d\n" , a );

return 0;
}

void new_printf ( char *buf , ... )
{

printf( buf , ... ); // the va list is passed to printf

}

The effect of the above would be that new_printf acts the same as
printf.

Thare are v* versions of the printf family of function for this
purpose. You want vprintf.
 
R

raphfrk

...



For some reason, nobody here wants to tell you about the vprintf() function.

Thanks. I guess I can assume from the existance of vprintf, that
there is no way to pass a va_list directly to printf itself ?
This is in line with official, stated, CLC policy - which is to never
give a sucker an even break.

Generally, they will correct every error in your code, including those
unrelated to the original question. However, they usually do also
answer the question too (and the list of errors can be helpful too).
 
K

Kenny McCormack

For some reason, nobody here wants to tell you about the vprintf() function.

Thanks. I guess I can assume from the existance of vprintf, that
there is no way to pass a va_list directly to printf itself ?[/QUOTE]

Correct. What this means is that every variable-number-of-args function
that exists must have a corresponding v...() version. Luckily, there
aren't very many (off the top of my head, I can only think of the printf
and scanf families) that "come with the system". But it also means that
any that you write yourself, you should also provide a v...() version of.

Which, IMHO, makes the whole va_args functionality rather useless. I
think it mainly exists for backwards compatibility with the existing
printf and scanf families.
Generally, they will correct every error in your code, including those
unrelated to the original question.

Human compilers, as they say. And about as useful. If I want a
compiler, I know where to find them.
However, they usually do also answer the question too (and the list of
errors can be helpful too).

My experience has been otherwise. Note that I am not talking about my
own issues - i.e., I'm not whining about them not answering my questions;
I have long since realized that looking for help here is like looking in
the sewer. I'm talking about my observations of years and years of them
joyously smackin' the newbies given any opportunity.

You may, of course, have another opinion. Fantasies die hard.
 
C

Chris Torek

... I guess I can assume from the existance of vprintf, that
there is no way to pass a va_list directly to printf itself ?

The conclusion here is correct -- you must call vprintf() rather
than printf() -- but the premise itself is faulty. In the past,
some implementations of printf() had a "%r" format that meant (more
or less) "the corresponding argument is a va_list that you should
switch to for all subsequent arguments". (In fact, at least one
%r directive took a format followed by a va_list, and worked them
in a sort of recursive fashion, hence the 'r' could be said to
stand for "recursive". Since %r was never standardized, other
printf()s that handled %r may have done other things.)

(To prove the need for the vprintf() family, you can simply read
the definition for printf() in the appropriate C Standard, and see
that there is no standard directive that takes a va_list.)

As a general rule, if you ever write your own variadic function:

TYPE my_variadic_function(T1 fixed1, T2 fixed2, ...) {
... some code will go here ...
}

you should begin by writing its entire guts as a "v"-prefixed
variant:

TYPE vmy_variadic_function(T1 fixed1, T2 fixed2, va_list ap) {
... the guts of the function ...
return whatever;
}

and then write the "wrapper" as the relatively short:

TYPE my_variadic_function(T1 fixed1, T2 fixed2, ...) {
TYPE ret;
va_list ap;

va_start(ap, fixed2);
ret = vmy_variadic_function(fixed1, fixed2, ap);
va_end(ap);
return ret;
}

That way, even though you (presumably) do not need it yourself yet,
the "v"-prefixed variant exists for whoever -- possibly you --
discovers a need for it later, in the same way that vprintf()
existed for you when you recently discovered a need for it.

The original C89 standard failed to provide a vscanf() family.
This is fixed in C99.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top