digitalmars.D.learn - 3 variant questions
- Saaa (5/5) May 11 2009 How do I return a variant type in D1?
- Christopher Wright (12/17) May 11 2009 Variant func()
- Saaa (10/27) May 11 2009 I can't seem to find Variant in D1
- Christopher Wright (3/16) May 11 2009 In D1/Phobos, you can use std.boxer.Box, which can work with variadic
- Saaa (3/5) May 11 2009 Ah, I see. boxer saves the typeinfo along the data.
- Daniel Keep (3/5) May 12 2009 You can't. You have to explicitly take the address of the arguments.
- Saaa (4/9) May 12 2009 Like this ?
- Daniel Keep (7/19) May 12 2009 import std.stdarg;
- Saaa (6/12) May 12 2009 I just noticed D1 does have std.stdarg.
- Daniel Keep (8/24) May 12 2009 You should never directly work with _argptr. It's not guaranteed to be
- Saaa (6/30) May 12 2009 I meant to write _argptr :)
- Daniel Keep (5/10) May 12 2009 Same as would happen if you incorrectly cast anything.
- grauzone (17/22) May 12 2009 Dear Saaa, these varargs suck badly and you shouldn't use them. It's so
- Saaa (11/33) May 12 2009 It doesn't say much about setting/changing the passed arguments.
- Saaa (16/22) May 12 2009 Calling the following returns an Access Violation Error after
How do I return a variant type in D1? After assessing that a variadic argument is an array, how do I check its depth? How do I set the variable given to me through the _arguments array? thanks :)
May 11 2009
Saaa wrote:How do I return a variant type in D1? After assessing that a variadic argument is an array, how do I check its depth? How do I set the variable given to me through the _arguments array? thanks :)Variant func() { return variant(5); } If you want to return something given from a runtime variadic argument list, neither Tango's Variant nor Phobos's Variant will work. Tango's Variant will get this capability soon, I hear. There is also reflect.variant: svn co http://felt-project.org/reflect reflect.variant allows you to create a Variant from a void* and a TypeInfo, like you get with varargs.
May 11 2009
"Christopher Wright" <dhasenan gmail.com> wrote in message news:gu8v1b$1uth$1 digitalmars.com...Saaa wrote:I can't seem to find Variant in D1How do I return a variant type in D1? After assessing that a variadic argument is an array, how do I check its depth? How do I set the variable given to me through the _arguments array? thanks :)Variant func() { return variant(5); }If you want to return something given from a runtime variadic argument list, neither Tango's Variant nor Phobos's Variant will work. Tango's:(Variant will get this capability soon, I hear.There is also reflect.variant: svn co http://felt-project.org/reflect reflect.variant allows you to create a Variant from a void* and a TypeInfo, like you get with varargs.Shouldn't it be possible to set an variadic argument? void func( ... ) { //something like this cast(int) _argptr = 10; }
May 11 2009
Saaa wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:gu8v1b$1uth$1 digitalmars.com...In D1/Phobos, you can use std.boxer.Box, which can work with variadic arguments.Saaa wrote:I can't seem to find Variant in D1How do I return a variant type in D1? After assessing that a variadic argument is an array, how do I check its depth? How do I set the variable given to me through the _arguments array? thanks :)Variant func() { return variant(5); }
May 11 2009
In D1/Phobos, you can use std.boxer.Box, which can work with variadic arguments.Ah, I see. boxer saves the typeinfo along the data. Sorry to ask, but do you have an answer to my other question as well? Passing variadic arguments as ref I think is what I am asking for :)
May 11 2009
Saaa wrote:... Passing variadic arguments as ref I think is what I am asking for :)You can't. You have to explicitly take the address of the arguments. -- Daniel
May 12 2009
Saaa wrote:Like this ? *_argptr = 10; :D I don't know how to tell the compiler I want to write data there.... Passing variadic arguments as ref I think is what I am asking for :)You can't. You have to explicitly take the address of the arguments. -- Daniel
May 12 2009
Saaa wrote:import std.stdarg; assert( _arguments[0] is typeid(int*) ); auto arg = va_arg!(int*)(_argptr); *arg = 10; Probably. -- DanielSaaa wrote:Like this ? *_argptr = 10; :D I don't know how to tell the compiler I want to write data there.... Passing variadic arguments as ref I think is what I am asking for :)You can't. You have to explicitly take the address of the arguments. -- Daniel
May 12 2009
I just noticed D1 does have std.stdarg. I shouldn't just search on the website :( (where it is missing on the phobos page)import std.stdarg; assert( _arguments[0] is typeid(int*) ); auto arg = va_arg!(int*)(_argptr); *arg = 10; Probably.:D-- DanielSo, you make arg point to the same as va_arg. Why is this extra step necessary and why won't simple casting not work?
May 12 2009
Saaa wrote:I just noticed D1 does have std.stdarg. I shouldn't just search on the website :( (where it is missing on the phobos page)No, va_arg is a function.import std.stdarg; assert( _arguments[0] is typeid(int*) ); auto arg = va_arg!(int*)(_argptr); *arg = 10; Probably.:D-- DanielSo, you make arg point to the same as va_arg.Why is this extra step necessary and why won't simple casting not work?You should never directly work with _argptr. It's not guaranteed to be a simple pointer. For example, I believe that GCC will sometimes use registers (God only knows WHY). var_arg!(T) will convert _argptr into the type you specify and it will also advance _argptr to the next argument. -- Daniel
May 12 2009
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message news:gubip2$187c$1 digitalmars.com...Saaa wrote:I meant to write _argptr :)I just noticed D1 does have std.stdarg. I shouldn't just search on the website :( (where it is missing on the phobos page)No, va_arg is a function.import std.stdarg; assert( _arguments[0] is typeid(int*) ); auto arg = va_arg!(int*)(_argptr); *arg = 10; Probably.:D-- DanielSo, you make arg point to the same as va_arg.ok...Why is this extra step necessary and why won't simple casting not work?You should never directly work with _argptr. It's not guaranteed to be a simple pointer. For example, I believe that GCC will sometimes use registers (God only knows WHY).var_arg!(T) will convert _argptr into the type you specify and it will also advance _argptr to the next argument.What would happen if you'd cast it incorrectly if it wasn't a simple pointer ? :D-- Daniel
May 12 2009
Saaa wrote:...Same as would happen if you incorrectly cast anything. i.e. anything. Segfault if you're lucky. If you're unlucky, random crashes. -- Danielvar_arg!(T) will convert _argptr into the type you specify and it will also advance _argptr to the next argument.What would happen if you'd cast it incorrectly if it wasn't a simple pointer ? :D
May 12 2009
Dear Saaa, these varargs suck badly and you shouldn't use them. It's so simple to introduce portability errors or heisenbugs, and it's incredibly hard to get it right. You're better off with alternatives. Alternative 1: Typesafe Variadic Functions Useful if the variadic arguments should have only one type. And they're very easy to use. It's documented somewhere on http://www.digitalmars.com/d/1.0/function.html Alternative 2: Tuples http://www.digitalmars.com/d/1.0/template.html#TemplateTupleParameter The variadic arguments can have any types, but such functions can't really be virtual methods or delegates.I think it's because GCC tries to keep the usual calling convention, where some arguments are passed as registers. Which is utterly pointless and stupid (ok, maybe it was easier to implement in gdc), and turns using varargs into hell. It would be so simple if _argptr was just an array of pointers to the actual arguments. It'd be so simple it makes me mad.Why is this extra step necessary and why won't simple casting not work?You should never directly work with _argptr. It's not guaranteed to be a simple pointer. For example, I believe that GCC will sometimes use registers (God only knows WHY).
May 12 2009
Dear Saaa, these varargs suck badly and you shouldn't use them. It's so simple to introduce portability errors or heisenbugs, and it'sheisenbugs :)incredibly hard to get it right. You're better off with alternatives. Alternative 1: Typesafe Variadic Functions Useful if the variadic arguments should have only one type. And they're very easy to use. It's documented somewhere on http://www.digitalmars.com/d/1.0/function.htmlIt doesn't say much about setting/changing the passed arguments. How do these differ? int test1( int i ...) { return i;} int test2( int i ) { return i;} test1(3); // returns 3 test2(3); // returns 3Alternative 2: Tuples http://www.digitalmars.com/d/1.0/template.html#TemplateTupleParameter The variadic arguments can have any types, but such functions can't really be virtual methods or delegates.Well, I should learn about them templates anyways :) Templates create the necessary appropriately typed instances of a function at compile-time.. seems more usefull as my get function should work with any type.I think it's because GCC tries to keep the usual calling convention, where some arguments are passed as registers. Which is utterly pointless and stupid (ok, maybe it was easier to implement in gdc), and turns using varargs into hell. It would be so simple if _argptr was just an array of pointers to the actual arguments. It'd be so simple it makes me mad.Why is this extra step necessary and why won't simple casting not work?You should never directly work with _argptr. It's not guaranteed to be a simple pointer. For example, I believe that GCC will sometimes use registers (God only knows WHY).
May 12 2009
import std.stdarg; assert( _arguments[0] is typeid(int*) ); auto arg = va_arg!(int*)(_argptr); *arg = 10; Probably. -- DanielCalling the following returns an Access Violation Error after correctly writing the two lines. void main() { int i; get( file, `i`, i); } public void get(in char[][] file, in char[] identifier, ...) { assert( _arguments[0] is typeid(int) ); writefln(`assert done`); auto arg = va_arg!(int*)(_argptr); writefln(`assign done`); *arg = 7; return; }
May 12 2009
Saaa Wrote:You get an AV because you're passing the argument by value. You need to pass its address instead. Try this: void main() { int i; get(file, "i", &i); writeln(i); } It will print "7".import std.stdarg; assert( _arguments[0] is typeid(int*) ); auto arg = va_arg!(int*)(_argptr); *arg = 10; Probably. -- DanielCalling the following returns an Access Violation Error after correctly writing the two lines. void main() { int i; get( file, `i`, i); } public void get(in char[][] file, in char[] identifier, ...) { assert( _arguments[0] is typeid(int) ); writefln(`assert done`); auto arg = va_arg!(int*)(_argptr); writefln(`assign done`); *arg = 7; return; }
May 12 2009
Ah of course, thanks.You get an AV because you're passing the argument by value. You need to pass its address instead. Try this: void main() { int i; get(file, "i", &i); writeln(i); } It will print "7".
May 12 2009