Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 29, 2004 variadic functions | ||||
---|---|---|---|---|
| ||||
Hi. Explain me, please: how i can write my variadic function f1, wich call another variadic function f2, and f1 pass variable number of input parameters to f2. For example, it is necessary to write function printErr(char[] formatStr, ...), wich call printf function: void printError(char[] formatStr, ...) { /*do something*/ printf("Error: " ~ formatStr, ...); /*pass all or some parameters to printf*/ /*do something*/ } Thanks |
September 29, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to novice | Can you just format it as a string then pass it to your print function?
void printError(char[] formatStr, ...)
{
writefln("Error : ", formatStr, formatString(_arguments, _argptr));
}
dchar[] formatString(TypeInfo[] arguments, void *argptr)
{
dchar[] message = null;
void putc(dchar c)
{
message ~= c;
}
std.format.doFormat(&putc, arguments, argptr);
return message;
}
novice wrote:
> Hi.
> Explain me, please:
> how i can write my variadic function f1, wich call another variadic function f2,
> and f1 pass variable number of input parameters to f2.
> For example, it is necessary to write function printErr(char[] formatStr, ...),
> wich call printf function:
>
> void printError(char[] formatStr, ...)
> {
> /*do something*/
> printf("Error: " ~ formatStr, ...); /*pass all or some parameters to printf*/
> /*do something*/
> }
>
> Thanks
>
>
|
September 29, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to novice | In article <cjdve9$mr8$1@digitaldaemon.com>, novice says... > >Hi. >Explain me, please: >how i can write my variadic function f1, wich call another variadic function f2, >and f1 pass variable number of input parameters to f2. >For example, it is necessary to write function printErr(char[] formatStr, ...), >wich call printf function: > >void printError(char[] formatStr, ...) >{ >/*do something*/ >printf("Error: " ~ formatStr, ...); /*pass all or some parameters to printf*/ >/*do something*/ >} > This is a problem that's as old as C itself. There is no way to pass the varadic argument list (...) itself, from one varadic function to another in an implicit fashion. However, the same workaround that works in C also works in D. Simply forward _argptr to the function that does the real work, along with the _arguments array that contains all the type information: > void f1(...){ > f2(_arguments,_argptr); // _argptr and _arguments are implicitly defined. > } > > void f2(TypeInfo[] _arguments,void** _argptr){ > // real code here > } Just so you know, this is how D uses 'doFormat' within writefln: it forwards the needed information to doFormat. http://www.digitalmars.com/d/std_format.html Additional info on varadic functions in D is here: http://www.digitalmars.com/d/function.html version(DNG) pragma(EricAnderton,"yahoo"); |
September 29, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to clayasaurus | Thank you, clayasaurus! But that code was just example... And it is a pity - absence of D function sprintf(). Yes, everybody can implement is in one minute. But IMHO it should be in standard lib. |
September 29, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to pragma | In article <cjea3e$t9j$1@digitaldaemon.com>, pragma says... <snip> > This is a problem that's as old as C itself. There is no way to pass the varadic argument list (...) itself, from one varadic function to another in an implicit fashion. > > However, the same workaround that works in C also works in D. Simply forward _argptr to the function that does the real work, along with the _arguments array that contains all the type information: Of course, this is of no use if you need to call an arbitrary third-party variadic function that doesn't have a version taking (_arguments, _argptr). This'll get even worse once closed-source libraries are coming out. >> void f1(...){ >> f2(_arguments,_argptr); // _argptr and _arguments are >> implicitly defined. >> } >> >> void f2(TypeInfo[] _arguments,void** _argptr){ >> // real code here >> } <snip> Hang on ... _argptr is a void*, not a void**. Stewart. |
September 29, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to pragma | >
>> void f1(...){
>> f2(_arguments,_argptr); // _argptr and _arguments are implicitly defined.
>> }
>>
>> void f2(TypeInfo[] _arguments,void** _argptr){
>> // real code here
>> }
>
But what if f2(...) is not in my sources, and declared as void f2(...) ?
For example f2(...) is str.stdio.writef(...)
Sorry for my stupidity, but
void f1(char[] formatStr, ...)
{
writef( formatStr,_arguments,_argptr);
}
produce runtime error...
|
September 29, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | In article <cjebin$uga$1@digitaldaemon.com>, Stewart Gordon says... > >In article <cjea3e$t9j$1@digitaldaemon.com>, pragma says... <snip> >> This is a problem that's as old as C itself. There is no way to pass the varadic argument list (...) itself, from one varadic function to another in an implicit fashion. >> >> However, the same workaround that works in C also works in D. Simply forward _argptr to the function that does the real work, along with the _arguments array that contains all the type information: > >Of course, this is of no use if you need to call an arbitrary third-party variadic function that doesn't have a version taking (_arguments, _argptr). This'll get even worse once closed-source libraries are coming out. Agreed. Variadics are a sticky business. It would be nice to have a way to copy the call stack into a new call to side-step this kind of limitation. I suppose it could be done in assembler easily enough, or D with enough pointer manipulation... any takers? > >>> void f1(...){ >>> f2(_arguments,_argptr); // _argptr and _arguments are >>> implicitly defined. >>> } >>> >>> void f2(TypeInfo[] _arguments,void** _argptr){ >>> // real code here >>> } ><snip> > >Hang on ... _argptr is a void*, not a void**. erp.. typeo. Thanks for catching that one. :) version(DNG) pragma(EricAnderton,"yahoo"); |
September 29, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to novice | "novice" <novice_member@pathlink.com> wrote in message news:cjebb3$ubp$1@digitaldaemon.com... > Thank you, clayasaurus! > > But that code was just example... > > And it is a pity - absence of D function sprintf(). Yes, everybody can implement > is in one minute. But IMHO it should be in standard lib. > format() in std.string. char[] s = format("hello %s", var); |
September 30, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to novice | In article <cjebb3$ubp$1@digitaldaemon.com>, novice says... >And it is a pity - absence of D function sprintf(). Yes, everybody can implement is in one minute. But IMHO it should be in standard lib. The C function sprintf() is a function with a built-in security hole (as in, potential for buffer overflows), and of course, it is still callable from D. Or did you mean a D replacement which returns a D char[] and can never buffer-overflow? Jill |
September 30, 2004 Re: variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arcane Jill | >The C function sprintf() is a function with a built-in security hole (as in, >potential for buffer overflows), and of course, it is still callable from D. > Thanks to Vathix for point me to sprintf analog: char[] s = std.string.format("hello %s", var); >Or did you mean a D replacement which returns a D char[] and can never buffer-overflow? Yes. |
Copyright © 1999-2021 by the D Language Foundation