www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - variadic functions

reply novice <novice_member pathlink.com> writes:
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
Sep 29 2004
next sibling parent reply clayasaurus <clayasaurus gmail.com> writes:
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
 
 

Sep 29 2004
parent reply novice <novice_member pathlink.com> writes:
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.
Sep 29 2004
next sibling parent "Vathix" <vathixSpamFix dprogramming.com> writes:
"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

 is in one minute. But IMHO it should be in standard lib.

format() in std.string. char[] s = format("hello %s", var);
Sep 29 2004
prev sibling parent reply Arcane Jill <Arcane_member pathlink.com> writes:
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
Sep 30 2004
parent reply novice <novice_member pathlink.com> writes:
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.
Sep 30 2004
parent "Walter" <newshound digitalmars.com> writes:
"novice" <novice_member pathlink.com> wrote in message
news:cjgpqb$2a1t$1 digitaldaemon.com...
The C function sprintf() is a function with a built-in security hole (as


potential for buffer overflows), and of course, it is still callable from



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.

std.string.format() does it.
Oct 01 2004
prev sibling parent reply pragma <pragma_member pathlink.com> writes:
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");
Sep 29 2004
next sibling parent reply Stewart Gordon <Stewart_member pathlink.com> writes:
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
 }


Hang on ... _argptr is a void*, not a void**. Stewart.
Sep 29 2004
parent pragma <pragma_member pathlink.com> writes:
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
 }


Hang on ... _argptr is a void*, not a void**.

erp.. typeo. Thanks for catching that one. :) version(DNG) pragma(EricAnderton,"yahoo");
Sep 29 2004
prev sibling parent reply novice <novice_member pathlink.com> writes:
 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...
Sep 29 2004
parent "Walter" <newshound digitalmars.com> writes:
"novice" <novice_member pathlink.com> wrote in message
news:cjec2m$uu3$1 digitaldaemon.com...
 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...

Yes, because writef expects ... arguments, not _arguments, _argptr. The two are not the same. For an example of how to do what you wish, see the source code \dmd\src\phobos\std\stdio.d.
Oct 01 2004