Jump to page: 1 2
Thread overview
va_start/va_end
May 01, 2004
J Anderson
May 02, 2004
Andrew Edwards
May 02, 2004
Andrew Edwards
May 02, 2004
J Anderson
May 02, 2004
J Anderson
May 02, 2004
Walter
May 02, 2004
Ben Hinkle
May 02, 2004
Hauke Duden
May 02, 2004
Hauke Duden
May 02, 2004
Walter
May 02, 2004
J C Calvarese
May 02, 2004
Walter
May 02, 2004
Andrew Edwards
May 02, 2004
Hauke Duden
May 02, 2004
Walter
May 01, 2004
What are the equivalent of:
va_start
and
va_end

in D?

Thanks.

PS - This is not meant to be an argument in anyway.  I just want to use the ... for multiple arguments.

-- 
-Anderson: http://badmama.com.au/~anderson/
May 02, 2004
"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c716pl$1ljo$1@digitaldaemon.com...
> What are the equivalent of:
> va_start
> and
> va_end
>
> in D?
>
> Thanks.
>
> PS - This is not meant to be an argument in anyway.  I just want to use the ... for multiple arguments.
>
> -- 
> -Anderson: http://badmama.com.au/~anderson/

There is no equivalent...You need to roll your own. I had played with this before, but am not sure if I came up with the correct syntax as I'm still having problems with it.

void va_start(inout va_list ap, char[] fmt)
{
  ap = cast(void*)(&args+args.size);
}

void va_end(inout va_list ap)
{
  ap = null;
}

if you come up with something that works please I'd like to get a hold of it.

Thanks,
Andrew



May 02, 2004
"Andrew Edwards" <edwardsac@spamfreeusa.com> wrote in message news:c71m0d$2ck4$1@digitaldaemon.com...
> "J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c716pl$1ljo$1@digitaldaemon.com...
> > What are the equivalent of:
> > va_start
> > and
> > va_end
> >
> > in D?
> >
> > Thanks.
> >
> > PS - This is not meant to be an argument in anyway.  I just want to use the ... for multiple arguments.
> >
> > -- 
> > -Anderson: http://badmama.com.au/~anderson/
>
> There is no equivalent...You need to roll your own. I had played with this before, but am not sure if I came up with the correct syntax as I'm still having problems with it.
>
> void va_start(inout va_list ap, char[] fmt)
> {
>   ap = cast(void*)(&args+args.size);
> }

sorry , that should read: ap = cast(va_list*)(&ap+ap.size);

> void va_end(inout va_list ap)
> {
>   ap = null;
> }
>
> if you come up with something that works please I'd like to get a hold of it.
>
> Thanks,
> Andrew
>
>
>


May 02, 2004
Andrew Edwards wrote:

>"Andrew Edwards" <edwardsac@spamfreeusa.com> wrote in message
>news:c71m0d$2ck4$1@digitaldaemon.com...
>  
>
>>"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message
>>news:c716pl$1ljo$1@digitaldaemon.com...
>>    
>>
>>>What are the equivalent of:
>>>va_start
>>>and
>>>va_end
>>>
>>>in D?
>>>
>>>Thanks.
>>>
>>>PS - This is not meant to be an argument in anyway.  I just want to use
>>>the ... for multiple arguments.
>>>
>>>-- 
>>>-Anderson: http://badmama.com.au/~anderson/
>>>      
>>>
>>There is no equivalent...You need to roll your own. I had played with this
>>before, but am not sure if I came up with the correct syntax as I'm still
>>having problems with it.
>>
>>void va_start(inout va_list ap, char[] fmt)
>>{
>>  ap = cast(void*)(&args+args.size);
>>}
>>    
>>
>
>sorry , that should read: ap = cast(va_list*)(&ap+ap.size);
>  
>

I don't get it, where do I get the parameter input from?  For example, at the moment I've got something like this:

void printp(char *format, ... )
{
   char [] TempStr;      TempStr.length =  (strlen((char*)format) * 2) + 50;  //Guess

   va_list varg;   //Holds arguments

   //Open the argument list
   va_start(varg,format);

       //Generate the string
       int x = _vsnprintf(TempStr, TempStr.length - 1, format, varg);
             //Increase size until it fits (not to efficient, but no overflows)
       while (x == -1)
       {
           //Increase size
           TempStr.length += 100;
           x = _vsnprintf(TempStr, TempStr.length - 1, format, varg);
       }
     //Close the argument list
   va_end(varg);
}

Of course the va_start doesn't work.

Thanks.

-- 
-Anderson: http://badmama.com.au/~anderson/
May 02, 2004
> void va_start(inout va_list ap, char[] fmt)
> {
>   ap = cast(void*)(&args+args.size);
> }
> 
> void va_end(inout va_list ap)
> {
>   ap = null;
> }

It's a bummer but I don't think "global" va_start and friends can be written without macros. I'd look at the printf code in std.outbuffer or std.stream for examples of how to use varargs in D. Maybe using nested functions would work but it wouldn't be very practical to have to define va_start inside every function that uses it.

-Ben
May 02, 2004
Andrew Edwards wrote:
> "J Anderson" <REMOVEanderson@badmama.com.au> wrote in message
> news:c716pl$1ljo$1@digitaldaemon.com...
> 
>>What are the equivalent of:
>>va_start
>>and
>>va_end
>>
>>in D?
>>
>>Thanks.
>>
>>PS - This is not meant to be an argument in anyway.  I just want to use
>>the ... for multiple arguments.
>>
>>-- 
>>-Anderson: http://badmama.com.au/~anderson/
> 
> 
> There is no equivalent...You need to roll your own. I had played with this
> before, but am not sure if I came up with the correct syntax as I'm still
> having problems with it.
> 
> void va_start(inout va_list ap, char[] fmt)
> {
>   ap = cast(void*)(&args+args.size);
> }
> 
> void va_end(inout va_list ap)
> {
>   ap = null;
> }
> 

This is wrong. ap is allocated on the stack AFTER the variable arguments. I'm not sure about the D calling convention, but when parameters are pushed in-order then it would have to look something like this:

void va_start(out va_list ap, inout void* prevArg)
{
  ap = (&prevArg)+prevArg.size;
}


This will only work if the previous argument is a pointer, though. A template helps:

typedef void* va_list;

template va_start(T)
{
  void va_start(out va_list ap, inout T prevArg)
  {
    ap = (cast(void*)&prevArg)+prevArg.size;
  }
}

template va_arg(T)
{
  T va_arg(inout va_list ap)
  {
    T arg=*cast(T*)ap;
    ap+=T.size;
    return arg;
  }
}

Unfortunately, since we have no implicit template instantiation, you then have to use it like this:

void printf(char[] fmt,...)
{
  va_list ap;

  va_start!(char[])(ap,fmt);

  if(....)
    int param=va_arg!(int)(ap);
}






May 02, 2004
Hauke Duden wrote:
> This is wrong. ap is allocated on the stack AFTER the variable arguments. I'm not sure about the D calling convention, but when parameters are pushed in-order then it would have to look something like this:


Just realized my error here: if the stack grows downwards (which, if memory serves, it usually does) and the arguments are still pushed in-order then this must look a little different:

typedef void* va_list;

template va_start(T)
{
  void va_start(out va_list ap, inout T prevArg)
  {
    ap = cast(void*)&prevArg;
  }
}

template va_arg(T)
{
  T va_arg(inout va_list ap)
  {
    ap-=T.size;
    return *cast(T*)ap;
  }
}



Hauke
May 02, 2004
J Anderson wrote:

> Andrew Edwards wrote:
>
>> "Andrew Edwards" <edwardsac@spamfreeusa.com> wrote in message
>> news:c71m0d$2ck4$1@digitaldaemon.com...
>>  
>>
>>> "J Anderson" <REMOVEanderson@badmama.com.au> wrote in message
>>> news:c716pl$1ljo$1@digitaldaemon.com...
>>>   
>>>
>>>> What are the equivalent of:
>>>> va_start
>>>> and
>>>> va_end
>>>>
>>>> in D?
>>>>
>>>> Thanks.
>>>>
>>>> PS - This is not meant to be an argument in anyway.  I just want to use
>>>> the ... for multiple arguments.
>>>>
>>>> -- 
>>>> -Anderson: http://badmama.com.au/~anderson/
>>>>     
>>>
>>> There is no equivalent...You need to roll your own. I had played with this
>>> before, but am not sure if I came up with the correct syntax as I'm still
>>> having problems with it.
>>>
>>> void va_start(inout va_list ap, char[] fmt)
>>> {
>>>  ap = cast(void*)(&args+args.size);
>>> }
>>>   
>>
>>
>> sorry , that should read: ap = cast(va_list*)(&ap+ap.size);
>>  
>>
>
> I don't get it, where do I get the parameter input from?  For example, at the moment I've got something like this:
>
> void printp(char *format, ... )
> {
>    char [] TempStr;      TempStr.length =  (strlen((char*)format) * 2) + 50;  //Guess
>
>    va_list varg;   //Holds arguments
>
>    //Open the argument list
>    va_start(varg,format);
>
>        //Generate the string
>        int x = _vsnprintf(TempStr, TempStr.length - 1, format, varg);
>              //Increase size until it fits (not to efficient, but no overflows)
>        while (x == -1)
>        {
>            //Increase size
>            TempStr.length += 100;
>            x = _vsnprintf(TempStr, TempStr.length - 1, format, varg);
>        }
>      //Close the argument list
>    va_end(varg);
> }
>
> Of course the va_start doesn't work.
>
> Thanks.
>
Oh I see. Your taking it from the stack.  Very clever.

-- 
-Anderson: http://badmama.com.au/~anderson/
May 02, 2004
Replace the va_start with:

    varg = (void*)&format + (void*).size;

Replace va_end with nothing.

"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c71qcc$2jnr$1@digitaldaemon.com...
> Andrew Edwards wrote:
>
> >"Andrew Edwards" <edwardsac@spamfreeusa.com> wrote in message news:c71m0d$2ck4$1@digitaldaemon.com...
> >
> >
> >>"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c716pl$1ljo$1@digitaldaemon.com...
> >>
> >>
> >>>What are the equivalent of:
> >>>va_start
> >>>and
> >>>va_end
> >>>
> >>>in D?
> >>>
> >>>Thanks.
> >>>
> >>>PS - This is not meant to be an argument in anyway.  I just want to use the ... for multiple arguments.
> >>>
> >>>-- 
> >>>-Anderson: http://badmama.com.au/~anderson/
> >>>
> >>>
> >>There is no equivalent...You need to roll your own. I had played with
this
> >>before, but am not sure if I came up with the correct syntax as I'm
still
> >>having problems with it.
> >>
> >>void va_start(inout va_list ap, char[] fmt)
> >>{
> >>  ap = cast(void*)(&args+args.size);
> >>}
> >>
> >>
> >
> >sorry , that should read: ap = cast(va_list*)(&ap+ap.size);
> >
> >
>
> I don't get it, where do I get the parameter input from?  For example, at the moment I've got something like this:
>
> void printp(char *format, ... )
> {
>     char [] TempStr;
>     TempStr.length =  (strlen((char*)format) * 2) + 50;  //Guess
>
>     va_list varg;   //Holds arguments
>
>     //Open the argument list
>     va_start(varg,format);
>
>         //Generate the string
>         int x = _vsnprintf(TempStr, TempStr.length - 1, format, varg);
>
>         //Increase size until it fits (not to efficient, but no overflows)
>         while (x == -1)
>         {
>             //Increase size
>             TempStr.length += 100;
>             x = _vsnprintf(TempStr, TempStr.length - 1, format, varg);
>         }
>
>     //Close the argument list
>     va_end(varg);
> }
>
> Of course the va_start doesn't work.
>
> Thanks.
>
> -- 
> -Anderson: http://badmama.com.au/~anderson/


May 02, 2004
Your use of templates to do varargs is cool. I made a couple of fixes, and the result is std.stdarg! It'll go out in the next release.

-------------------------------------------------
/*
 * Placed in public domain.
 * Written by Hauke Duden and Walter Bright
 */

module std.stdarg;

typedef void* va_list;

template va_start(T)
{
    void va_start(out va_list ap, inout T parmn)
    {
 ap = cast(va_list)(cast(void*)&parmn + ((T.sizeof + int.sizeof - 1) &
~(int.sizeof - 1)));
    }
}

template va_arg(T)
{
    T va_arg(inout va_list ap)
    {
 T arg = *cast(T*)ap;
 ap = cast(va_list)(cast(void*)ap + ((T.sizeof + int.sizeof - 1) &
~(int.sizeof - 1)));
 return arg;
    }
}

void va_end(va_list ap)
{
}
------------------------------------------------------------------
Here's a little test program to show how to use it:

------------------------------------------------------------------
import std.stdarg;

int foo(char *x, ...)
{
    va_list ap;

    va_start!(typeof(x))(ap, x);
    printf("&x = %p, ap = %p\n", &x, ap);

    int i;
    i = va_arg!(typeof(i))(ap);
    printf("i = %d\n", i);

    long l;
    l = va_arg!(typeof(l))(ap);
    printf("l = %lld\n", l);

    uint k;
    k = va_arg!(typeof(k))(ap);
    printf("k = %u\n", k);

    va_end(ap);

    return i + l + k;
}

void main()
{
    int j;

    j = foo("hello", 3, 23L, 4);
    printf("j = %d\n", j);
    assert(j == 30);
}
------------------------------------------------------


« First   ‹ Prev
1 2