I know that variadic macros have been added in C99 (and via GNU extensions). I've been wondering if there is a nice alternative in ANSI C.
I've come up with something like this, but it's still kind of awkward:
void log_info(const char *file, int line, const char *fmt, ...)
{
#ifdef DEBUG
va_list ap;
char newfmt[1024] = { 0 };
va_start(ap, fmt);
sprintf(newfmt, "[INFO] (%s:%d): %s\n", file, line, fmt);
vfprintf(stderr, newfmt, ap);
va_end(ap);
#endif
}
So that this can be called like this:
log_info(__FILE__, __LINE__, "info message: %s %d", "helloworld", 12);
There is nothing wrong with this approach, however I'm wondering if there is a nicer way of doing it? Eg. with no need to specify file/line everytime.
I'd appreciate any feedback. :)
Edit: By ANSI C here I mean C89.
Edit: The answer below is fine but I believe given it requires running the printing command twise it may impose some thread-safety issues as it is. Another alternative might be to use define to minimize the typing (also quite ugly):
#define __FL__ __FILE__, __LINE__
and then run the command like:
log_info(__FL__, "info message: %s %d", "helloworld", 12);
It's a little ugly, but a sequence of comma-separated expressions in parentheses can be treated as a single argument.
An example:
#include <stdio.h>
#define LOG(args) (printf("LOG: %s:%d ", __FILE__, __LINE__), printf args)
int main(void) {
LOG(("Hello, world\n"));
int n = 42;
LOG(("n = %d\n", n));
return 0;
}
The output:
LOG: c.c:6 Hello, world
LOG: c.c:8 n = 42
Note that this requires an extra set of parentheses in the call.
Here is an even uglier option, but uses single call to printf:
#define PROMPT "[INFO] (%s:%d): "
#define FL __FILE__, LINE__
#define DEBUG0(fmt) printf(PROMPT fmt, FL);
#define DEBUG1(fmt, a1) printf(PROMPT fmt, FL, a1);
#define DEBUG2(fmt, a1, a2) printf(PROMPT fmt, FL, a1, a2);
#define DEBUG3(fmt, a1, a2, a3) printf(PROMPT fmt, FL, a1, a2, a3);
and so on until the most number of arguments that you call the macro with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With