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