I've got this logging system for which I'm looking to shortcut some of the string manipulation.
The logging system is used via functional macros which then forward to a single function call. E.g. #define Warning(...) LogMessage(eWarning, __VA_ARGS__);
.
LogMessage then does a snprintf
into a new buffer and then presents that message to whatever log targets happen to be installed; printf, OutputDebugString, etc.
Unfortunately, I've run into a problem where the buffer that we have isn't big enough, so the output gets truncated. I also realized that this method will fail if the output message has percent symbols in it, as snprintf will try to process the va_args. Finally, as the majority of our log messages do not use the va_args, it seems silly to copy the string just to present it to the loggers.
So- given my function prototype, should I be able to overload based on the presence of the ellipses? In other words, should I be able to assume that I can do something like:
LogMessage(LogLevel, const char* message, ...);
LogMessage(LogLevel, const char* message);
My google attempts haven't yielded anything particularly useful (just showing me that ellipses will match if nothing else does, varying from my requirements that nothing matches), and my initial stab at an implementation just gave me an ambiguous function call error.
With the error, I should just accept that I can't do this, but I'm wondering if it's just the compiler I'm using or if maybe I'm doing it wrong. I can achieve a similar effect with
// edited version of what I really have to remove our local APIs,
// please excuse minor errors
const char* message = NULL;
char buffer[512];
va_list args;
va_start(args, format);
if(strcmp(format, "%s") == 0) {
message = va_arg(args, const char*);
}
else if (strchr(format, '%') == NULL) {
message = format;
}
else {
vsnprintf(buffer, 512, format, args);
message = buffer;
}
va_end(args);
...but this seems wasteful in the typical case which can be known simply by the number of parameters being passed. E.g. if ellipses don't match anything, select the other function? If this doesn't work, is there another method I can try that doesn't require the user to decide with the macro name which function will be called? Honestly it's not even as much about the "waste" once I realized that if someone haphazardly said Error("Buffer not 100% full");
in their log message and got "Buffer not 1007.732873e10ull" as a result.
Edit: While my example has been answered by a "don't do that," can the question itself be answered?