I have found no way to merge the first printf into the second:
unsigned get_time_now(void) {return 1;}
#define DEBUG_PRINT 1
#define debug_tcprintf(fmt, ...) do { \
if (DEBUG_PRINT) { \
unsigned p_time_now = get_time_now(); \
printf ("%u ms ", p_time_now); \
printf(fmt, __VA_ARGS__); \
} \
} while (0)
I need to get this done to get an atomic debug_tcprintf. The macro above has been taken from this Stack Overflow question.
I am doing code in XC that runs on an XMOS multi-logical-core processor. It compiles XC, C and C++, but the code example is from a C code part. It is similar for XC except that it has a timer defined in the language.
If it's not possible to merge the two in one printf, an option may perhaps be to create a string and use sprintf instead? I'd rather not, since such an array might easily overflow.
You need to use string concatenation and token pasting. Notice in the snippet below there is no comma after the first string literal -- this is intentional.
The string concatenation allows you to prepend the
"%u ms "
portion onto the supplied format string. Token pasting (the##
operator) accounts for the possibility of your macro being invoked with or without additional variadic arguments (beyond just the format string).This only works if you call the macro with a string literal as the format string.
Addendum: The way token-pasting is used in this example is actually a gcc extension to the standard C pre-processor. If you are not using the gcc compiler, you may need to omit the
##
operator. The downside to this is that you then cannot call your macro with only one argument; for example,debug_tcprintf ("hello world")
will not work. A simple workaround is to usedebug_tcprintf ("%s", "hello world")
in such a scenario.