Jump to page: 1 2
Thread overview
variadic functions
Sep 29, 2004
novice
Sep 29, 2004
clayasaurus
Sep 29, 2004
novice
Sep 29, 2004
Vathix
Sep 30, 2004
Arcane Jill
Sep 30, 2004
novice
Oct 02, 2004
Walter
Sep 29, 2004
pragma
Sep 29, 2004
Stewart Gordon
Sep 29, 2004
pragma
Sep 29, 2004
novice
Oct 02, 2004
Walter
September 29, 2004
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
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
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
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
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
>
>> 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
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
"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
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
>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.


« First   ‹ Prev
1 2