May 12, 2009 Re: 3 variant questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | "Daniel Keep" <daniel.keep.lists@gmail.com> wrote in message news:gubip2$187c$1@digitalmars.com... > > > 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) >> >>> import std.stdarg; >>> >>> assert( _arguments[0] is typeid(int*) ); >>> auto arg = va_arg!(int*)(_argptr); >>> *arg = 10; >>> >>> Probably. >> :D >>> -- Daniel >> >> So, you make arg point to the same as va_arg. > > No, va_arg is a function. I meant to write _argptr :) > >> 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). ok... > > 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 Re: 3 variant questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa |
Saaa wrote:
> ...
>> 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
Same as would happen if you incorrectly cast anything.
i.e. anything. Segfault if you're lucky. If you're unlucky, random crashes.
-- Daniel
|
May 12, 2009 Re: 3 variant questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | >
> import std.stdarg;
>
> assert( _arguments[0] is typeid(int*) );
> auto arg = va_arg!(int*)(_argptr);
> *arg = 10;
>
> Probably.
>
> -- Daniel
Calling 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 Re: 3 variant questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | Saaa Wrote:
> >
> > import std.stdarg;
> >
> > assert( _arguments[0] is typeid(int*) );
> > auto arg = va_arg!(int*)(_argptr);
> > *arg = 10;
> >
> > Probably.
> >
> > -- Daniel
>
> Calling 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;
> }
>
>
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 Re: 3 variant questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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. >> 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). 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. |
May 12, 2009 Re: 3 variant questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | >>
>
> 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".
Ah of course, thanks.
|
May 12, 2009 Re: 3 variant questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to grauzone | > 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 heisenbugs :) > 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 It 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 3 > > 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. 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. > >>> 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). > > 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. |
Copyright © 1999-2021 by the D Language Foundation