In the body of "v_format_string()", I allocate a certain amount of memory, store it in a std::unique_ptr<char[]> called 'p' by way of a call to 'p.reset(allocated_memory)', and then attempt to call:
n = vsnprintf(&p[0], allocated_size, format.c_str(), args);
and if 'n' is positive and less than 'allocated_size' the function allocates twice as much memory, storing it in 'p' with yet another call to 'reset()', and attempts another 'vsprintf()' call, repeating the process until enough memory is used; that's the plan. It seems, however, a segmentation fault occurs when I attempt to do so. Is my logic correct? Can a 'va_list' parameter not be referenced multiple times in the same function? More importantly, is there a vsprintf-like function for std::string's? Note: Since I am trying to get 'out()' to work similar to 'printf()', I cannot know the format strings ahead of time, if this fact makes any difference.
@Yay295: Thanks for pointing this out. However, as noted, in the body of "v_format_string()", I do use that member function. Or are You referring to another use?
@xuinkrbin: I did notice that. It just seemed like you were asking if there was another way to do it. There isn't as far as I know (which admittedly isn't that far), so I was just confirming that what you did was correct.
@helios: I don't see how One concludes "Variadic functions are rather passé".
@Yay295: Actually, I do have that call in code. I have a typo in the original post which I will correct if I can.
@Everyone: What I have posted is a stripped down version of the actual function, which performs other actions including, but not limited to, outputting the resulting string to a second stream, if this fact makes any difference.
I don't see how One concludes "Variadic functions are rather passé".
If you were programming in C, you'd have no comfortable alternative to variadic functions for passing an indeterminate amount of parameters of indeterminate type to an object. With more expressive power of C++ (function overloading, operator overloading, templates, etc. etc.) variadic functions are a step backwards in almost every situation.
@helios: Interesting explanation. In this particular project, I have literally over a thousand calls to 'printf()' which need to be replaced with this new function. In order to ease transition to the use of this new function, the hope was a drop-in replacement could be crafted. Do You have any additional insights to help in this regard?
Well, as a zero-effort drop-in replacement, you could do something like #defineing printf to refer to an object of your own that overloads the comma operator. That should be possible with variadic macros.
@JLBorges: YES!!! VA_COPY!!! I plunked that into 'v_format_string()' and all is well. ... At least as far as I can tell. ;-) Thank You!
@helios: I will definitely keep Your points in Mind going forward and see if I cannot nudge the project in the direction to which You have hinted/implied/suggested/whatever ...
As far as possible, unless you are dealing with a toy code-base, avoid #define of well-known identifiers like printf().
And avoid overloading the sequencing (comma) operator; it engenders behaviour that is unintuitive.
A set of overloaded functions is all that is required.
Adding to what JLBorges says about macro's and 'printf', defining 'printf' (or any other identifier in the standard library or any other reserved identifier) to be a macro results in undefined behavior according to the ISO C/C++ standards. As such, I might advise NEVER defining a macro with such a name.