digitalmars.D - working va_arg implementation
- Hauke Duden (29/29) May 02 2004 After not being sure in my previous post, I ran a few tests with a
 - J Anderson (4/33) May 02 2004 Thanks a lot! Parhaps this should go into phobos?
 - Achilleas Margaritis (15/56) May 02 2004 In order to do safe varargs, D should have a 'variant' primitive type wh...
 - Andrew Edwards (10/30) May 02 2004 [SNIP] va_arg implimentation [/SNIP]
 - Achilleas Margaritis (3/38) May 03 2004 It is the only solution that makes sense for variable arguments. Does Wa...
 - Andy Friesen (19/34) May 03 2004 If you have to check the type at runtime like that, it's not very
 - Hauke Duden (5/7) May 02 2004 If Walter wants to have it in there - sure.
 - Walter (3/3) May 02 2004 It's almost perfect - but the advancement of ap doesn't take into accoun...
 
After not being sure in my previous post, I ran a few tests with a 
template implementation for varargs until I got it to work.
This is what I came up with. It works with the normal D calling 
convention on Windows:
typedef void* va_list;
template va_start(T)
{
	va_list va_start(inout T prevArg)
	{
		return cast(va_list) (&prevArg + 1);
	}
}
template va_arg(T)
{
	T va_arg(inout va_list ap)
	{
		T arg=*cast(T*)ap;
		ap = cast(va_list) ((cast(T*)ap) +1);
		return arg;
	}
}
usage:
void printf(char[] fmt,...)
{
   va_list argList = va_start!(char[])(fmt);
   int param1=va_arg!(int)(argList);
   double param2=va_arg!(double)(argList);
   etc...
}
 May 02 2004
Hauke Duden wrote:
 After not being sure in my previous post, I ran a few tests with a 
 template implementation for varargs until I got it to work.
 This is what I came up with. It works with the normal D calling 
 convention on Windows:
 typedef void* va_list;
 template va_start(T)
 {
     va_list va_start(inout T prevArg)
     {
         return cast(va_list) (&prevArg + 1);
     }
 }
 template va_arg(T)
 {
     T va_arg(inout va_list ap)
     {
         T arg=*cast(T*)ap;
         ap = cast(va_list) ((cast(T*)ap) +1);
         return arg;
     }
 }
 usage:
 void printf(char[] fmt,...)
 {
   va_list argList = va_start!(char[])(fmt);
   int param1=va_arg!(int)(argList);
   double param2=va_arg!(double)(argList);
   etc...
 }
Thanks a lot!  Parhaps this should go into phobos?
-- 
-Anderson: http://badmama.com.au/~anderson/
 May 02 2004
"J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:c72ro7$15jj$1 digitaldaemon.com...Hauke Duden wrote:In order to do safe varargs, D should have a 'variant' primitive type which can be anything. When pushing varargs on the stack, a static array of variants is created, then accessed in the function as an array, using RTTI. For example: void printf(...) { foreach(variant v; printf.args) { switch (typeof(v)) { case typeof(int): case typeof(string): } } }After not being sure in my previous post, I ran a few tests with a template implementation for varargs until I got it to work. This is what I came up with. It works with the normal D calling convention on Windows: typedef void* va_list; template va_start(T) { va_list va_start(inout T prevArg) { return cast(va_list) (&prevArg + 1); } } template va_arg(T) { T va_arg(inout va_list ap) { T arg=*cast(T*)ap; ap = cast(va_list) ((cast(T*)ap) +1); return arg; } } usage: void printf(char[] fmt,...) { va_list argList = va_start!(char[])(fmt); int param1=va_arg!(int)(argList); double param2=va_arg!(double)(argList); etc... }Thanks a lot! Parhaps this should go into phobos? -- -Anderson: http://badmama.com.au/~anderson/
 May 02 2004
"Achilleas Margaritis" <axilmar in.gr> wrote in message news:c72s1u$167n$1 digitaldaemon.com..."J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:c72ro7$15jj$1 digitaldaemon.com...[SNIP] va_arg implimentation [/SNIP]Hauke Duden wrote:which-- -Anderson: http://badmama.com.au/~anderson/In order to do safe varargs, D should have a 'variant' primitive typecan be anything. When pushing varargs on the stack, a static array of variants is created, then accessed in the function as an array, usingRTTI.For example: void printf(...) { foreach(variant v; printf.args) { switch (typeof(v)) { case typeof(int): case typeof(string): } } }This was exactly my suggestion a few months back (http://www.digitalmars.com/drn-bin/wwwnews?D/25025). IMHO this is an elegant solution to both variable argument and typesafe functions. Regards, Andrew
 May 02 2004
In article <c72tu3$196a$1 digitaldaemon.com>, Andrew Edwards says..."Achilleas Margaritis" <axilmar in.gr> wrote in message news:c72s1u$167n$1 digitaldaemon.com...It is the only solution that makes sense for variable arguments. Does Walter know about it ?"J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:c72ro7$15jj$1 digitaldaemon.com...[SNIP] va_arg implimentation [/SNIP]Hauke Duden wrote:which-- -Anderson: http://badmama.com.au/~anderson/In order to do safe varargs, D should have a 'variant' primitive typecan be anything. When pushing varargs on the stack, a static array of variants is created, then accessed in the function as an array, usingRTTI.For example: void printf(...) { foreach(variant v; printf.args) { switch (typeof(v)) { case typeof(int): case typeof(string): } } }This was exactly my suggestion a few months back (http://www.digitalmars.com/drn-bin/wwwnews?D/25025). IMHO this is an elegant solution to both variable argument and typesafe functions. Regards, Andrew
 May 03 2004
Achilleas Margaritis wrote:
 In order to do safe varargs, D should have a 'variant' primitive type which
 can be anything. When pushing varargs on the stack, a static array of
 variants is created, then accessed in the function as an array, using RTTI.
 For example:
 
 void printf(...)
 {
     foreach(variant v; printf.args) {
         switch (typeof(v)) {
             case typeof(int):
 
             case typeof(string):
         }
     }
 }
If you have to check the type at runtime like that, it's not very 
typesafe. ;)
I see two resolutions to this issue.  The easy one is the opCall idiom: 
  stdout.print("aoeuaoeu") (42) (3.141596) ();
The hard (but awesome) one requires some sort of type deduction.  Given 
that, it would be very simple to add a symbol to the language that 
represents "all the other arguments".  Normal overloading rules would apply:
    void print(char[] s, other) {
       puts(s);
       print(other);
    }
    void print(int i, other) {
       printf("%i", i);
       print(other);
    }
    void print() {
    }
  -- andy
 May 03 2004
J Anderson wrote:Thanks a lot! Parhaps this should go into phobos?If Walter wants to have it in there - sure. And before any licensing stuff comes up: I hereby place the code in the public domain. Hauke
 May 02 2004
It's almost perfect - but the advancement of ap doesn't take into account objects that take more than a pointer size of the stack. I've posted a corrected version in the other thread. Thanks!
 May 02 2004








 
 
 
 Achilleas Margaritis <Achilleas_member pathlink.com> 