1

I am attempting to write a logging function which takes a variadic argument list and prints in a safe manor.
vprintf seems like the obvious answer, but I cannot seem to find a safe way to handle when the format string expects more arguments than were provided.

Additionally, it would be very nice if I could rearrange the order the parameters are printed.
This second requirement led me to boost::format, which seems to be exactly what I want, except that it does not accept a va_list for input.

I have done some extensive searching and the closest I could get was this solution:
boost::format with variadic template arguments

Unfortunately I am restricted to a specific gcc version which does not seem to include the std::initializer_list

In my searching, I have stumbled upon boost::preprocessor which seems like it should be able to accomplish what I want, but I am struggling with the implementation of it.

So, ideally, what I'm searching for is something that works as follows:

void loggerFunc(const char* msgFormat, ...){
    boost::format f(msgFormat);

    va_list args;
    va_start(args, msg);

    f & MagicalFunctionCall(args);

    va_end(args);
}

Where this MagicalFunctionCall(args) would convert my args, for example:
1, "Test", 3.4, "OtherString"
into something like:
1 & "Test" & 3.4 & "OtherString"

I'm not necessarily tied to boost::preprocessor or anything boost really, but it would be ideal to accomplish this without pulling in any additional 3rd party dependencies (we already use boost elsewhere in the project). I just suggested those libraries, because they seemed to be the most promising in accomplishing all of the above.

Thanks!

DaBernMon
  • 48
  • 4

1 Answers1

2

Instead of Boost Format you could use the fmt library which supports older compilers ({fmt} 4 supports gcc 4.4):

void loggerFunc(const char *format, fmt::ArgList args) {
  std::string s = fmt::format(format, args);
  // log s
}
FMT_VARIADIC(void, loggerFunc, const char *)

The loggerFunc generated by FMT_VARIADIC can be used with variable number of arguments:

loggerFunc("{} {} {} {}", 1, "Test", 3.4, "OtherString");

Disclaimer: I'm the author of the fmt library.

vitaut
  • 49,672
  • 25
  • 199
  • 336
  • 1
    Thanks for the response! My team was pretty set on sticking to our current dependencies, but I'll definitely look to use this on future projects, it looks very helpful! Also, in reading through your doc I learned something about the regular `printf` command that seemed to give me a viable workaround for this current issue. – DaBernMon Feb 15 '18 at 18:46