stdarg.h question

stdarg.h question

Post by Mark » Thu, 27 Feb 2003 20:46:40



Hi,

I have a function which has a variable number of arguments. So I use
stdarg.h and va_start, va_arg and va_end to access the arguments. This works
fine. The problem is that I need a wrapper around this function. So this
function also makes use of va_start, va_arg and va_end.

So now comes the hard part (for me), I need to pass all the arguments to the
function call of the original function. In my enthousiasm I wirst did it
like this:

wrapper(int ref, ...)
{
  va_list ap;
  va_start(ap, ref);

  orig_function(ref, &va_arg(ap));

  va_end(ap);

Quote:}

of course this doesn't work because I then pass the address of the first
argument to the wrapper as an argument to the original function. But the
original function expects the data itself. So my problem is how do I get the
actual data to be copied to the right way. I was thinking of memcpy some
stuff, but I don't know what I should memcpy, and I think it will not be
portable at all. And it would be nice if there is a portable solution for
this.

I could use an array as an argument which contains the data in stead of
using variable arguments, but that is not what I want. It is very anoying to
put all your arguments in an array before you can call your function.

Does anybody has a solution for this?

Thanks,
  Mark

 
 
 

stdarg.h question

Post by Kasper Dupon » Thu, 27 Feb 2003 20:59:54



> wrapper(int ref, ...)
> {
>   va_list ap;
>   va_start(ap, ref);

>   orig_function(ref, &va_arg(ap));

>   va_end(ap);
> }

[...]

> Does anybody has a solution for this?

Yes, don't use the orig_function, but rather the v variant
of the function. So if the orig_function was sprintf, you
should instead use vsprintf. If there is not implemented a
v variant of the orig_function, then you have a problem.
You might be able to use a gcc extension instead in that
case, but I'm not sure how well it is going to work. Check
the gcc info pages under C Extensions Constructing Calls.

--
Kasper Dupont -- der bruger for meget tid p? usenet.

for(_=52;_;(_%5)||(_/=5),(_%5)&&(_-=2))putchar(_);

 
 
 

stdarg.h question

Post by M?ns Rullg? » Thu, 27 Feb 2003 21:30:34



> Yes, don't use the orig_function, but rather the v variant
> of the function. So if the orig_function was sprintf, you
> should instead use vsprintf. If there is not implemented a
> v variant of the orig_function, then you have a problem.
> You might be able to use a gcc extension instead in that
> case, but I'm not sure how well it is going to work. Check
> the gcc info pages under C Extensions Constructing Calls.

 - Built-in Function: void * __builtin_apply (void (*FUNCTION)(), void
          *ARGUMENTS, size_t SIZE)
     This built-in function invokes FUNCTION with a copy of the
     parameters described by ARGUMENTS and SIZE.

     The value of ARGUMENTS should be the value returned by
     `__builtin_apply_args'.  The argument SIZE specifies the size of
     the stack argument data, in bytes.

     This function returns a pointer to data describing how to return
     whatever value was returned by FUNCTION.  The data is saved in a
     block of memory allocated on the stack.

     It is not always simple to compute the proper value for SIZE.  The
     value is used by `__builtin_apply' to compute the amount of data
     that should be pushed on the stack and copied from the incoming
     argument area.

This last paragraph indicates some trouble.  I also wonder how this
works with machines (e.g. Alpha) where arguments are passed in
registers.

Anyhow, I made a little test program.

---CUT---
#include <stdio.h>

int
wrap_printf(char *fmt, ...)
{
    void *args, *ret;

    args = __builtin_apply_args();
    ret = __builtin_apply(printf, args, 12);
    __builtin_return(ret);

Quote:}

int main(int argc, char **argv)
{
    wrap_printf("%s %i\n", "foo", 17);
    return 0;
Quote:}

---CUT---

It looks like the size argument to __builtin_apply should be
4+4*(#-of-args) for ia32 machines.  This seems sensible.

--
M?ns Rullg?rd

 
 
 

1. stdarg.h problem during compilation (Redhat 8.0)

I'm compiling a large program on a Linux Redhat 8.0 and receiving the
following
compiler error for a couple of my packages:

/usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stdarg.h:43: parse
error, token 258
/usr/include/libio.h:463: parse error, token 258
/usr/include/libio.h:465: parse error, token 258
/usr/include/stdio.h:307: parse error, token 258
/usr/include/stdio.h:309: parse error, token 258
/usr/include/stdio.h:313: parse error, token 258
/usr/include/stdio.h:324: parse error, token 258

Line 43 of the stdarg.h is as follows:

typedef __builtin_va_list __gnuc_va_list;

I've tried to search the net for any info, but haven't found much...
if anyone could provide some help, I would appreciate it.

2. nvidia graphics card vs nforce2 igp?

3. stddef.h, stdarg.h, float.h where??

4. installed/system user id's

5. Does kernel use system stdarg.h?

6. Linux make problems

7. >> Need stdarg.h for GCC 2.7.0 <<

8. Solaris and Webdesign

9. Problem with variable argument functions ... (stdarg)

10. stdarg.h missing?

11. Solaris x86 - stdarg.h problem

12. stdarg.h

13. stdarg.h not found...