I have a LOG(fmt, ...)
macro that does not work when using a char buf[]
as fmt
.
The code below is a complete (not actually) working example of the code. In some_function()
, I am trying to use LOG()
in two different ways but only the first approach works.
To solve the problem, I have tried using #define LOG_STR(x) #x
in the following way:
To stringify what is received in the #define LOG
by applying LOG_STR()
to format
like this: LOG_STR(format)
; and
To apply LOG_STR()
directly to the printing like this: LOG(LOG_STR(fmt), 6)
.
Neither approach works and in fact I get segfault out of it.
#include <stdio.h>
#define LOG(format, ...) do { \
fprintf(stderr, "[LOG] " format " [%s]\n", \
##__VA_ARGS__, __func__); \
} while (0)
static void some_function()
{
// This works
LOG("This is a number: %d", 5);
// This does not work
const char fmt[] = "This is a number: %d";
LOG(fmt, 6);
}
int main(void)
{
some_function();
return 0;
}
When I compile the code above I get the following error:
$ gcc -o log-macro-str log-macro-str.c
log-macro-str.c: In function ‘some_function’:
log-macro-str.c:15:6: error: expected ‘)’ before ‘fmt’
LOG(fmt, 6);
^
log-macro-str.c:4:29: note: in definition of macro ‘LOG’
fprintf(stderr, "[LOG] " format " [%s]\n", \
^~~~~~
I'd like to use LOG()
in both ways as done in some_function()
or without modifiers and just printing a string. I suspect I might have to stringify the format
part but I can't seem to do it correctly.
What am I doing wrong, and how can I solve this issue?
The stringify operator, #
in a macro, converts preprocessor tokens to text in a string literal. It will not change the contents of a char
buffer to a compile-time string literal.
To make your macro work, use multiple fprintf
statements:
#define LOG(format, ...) do { \
fprintf(stderr, "[LOG] "); \
fprintf(stderr, format, __VA_ARGS__); \
fprintf(stderr, " [%s]\n", __func__); \
} while (0)