variadic function: passing args

Georg Wrede georg.wrede at nospam.org
Thu Jul 6 09:12:31 PDT 2006


Chris Nicholson-Sauls wrote:
> icee wrote:
> 
>> is there a way to pass the ... args from one variadic function to another
>> variadic function?
>>
>> consider such case:
>> void vf1(int a, ...) {
>>
>> vf2(...);
>> }
>> void vf2(...) {
>> }
>>
>> can vf2 take _arguments and _argptr from vf1?
>>
>>
> 
> Simply way to do it, is to write vf2 twice, once as a variadic wrapper, 
> and once taking a vararg pair.  In other words:
> 
> # import std .stdarg ;
> #
> # void vf2 (...) { vf2(_arguments, _argptr); }
> #
> # void vf2 (TypeInfo[] _arguments, va_list _argptr) {
> #   /* real work */
> # }
> 
> Sad to say, this is one time when I do start to miss a preprocessor just 
> a little.  It'd be somewhat nice to be able to do:
> 
> ########## module altvararg ;
> # import std .stdarg ;
> #
> # #define ALT_VARIADIC(FNAME) \
> #   void FNAME (...) { FNAME(_arguments, _argptr; } \
> #   void FNAME (TypeInfo[] _arguments, va_list _argptr)
> #
> 
> ########## module foo ;
> # import altvararg ;
> #
> # ALT_VARIADIC(vf2) {
> #   /* real work */
> # }
> 
> Maybe if we /did/ have a way it would be better.  Maybe something like:
> # vf2(_arguments ... _argptr);
> 
> Where the '...' in this case has become an operator meaning to pass 
> these varargs to the callee as such.  Not sure if it'd be the best 
> syntax, but its the simplest thing that comes to mind.

Suppose we had a new keyword, variadic. Then the compiler could 
internally accomplish what you propose, by just rewriting, and no 
complicated changes are needed!

void variadic foo(...)
{
     // real work
}

Of course, here the "..." is redundant. So maybe the syntax could be 
even more simple:

void foo(...) {
     // real work
}

So, in essence, the compiler constructs two functions (instead of one):

whateverReturnType foo(...) {
     // real work
}

gets rewritten as:

whateverReturnType foo(...) { foo(_arguments, _argptr; }
whateverReturnType foo(TypeInfo[] _arguments, va_list _argptr)
{
     // real work
}

Now, another change is of course handy here, and that is, if a function 
gets invoked like

blah = foo(...);

then it will be rewritten as:

blah = foo(_arguments, _argptr);

which should be no big deal to implement, right? Major syntactic sugar, 
I admit, but then again, the whole ... busines is just that. (Or else we 
would just pass Object[] type variables, right?)

----

This makes one actually wish for some sugar for manipulation of 
runtime-generated argument lists! (Lisp, watch out, we're coming!)



More information about the Digitalmars-d mailing list