Question

I got next debug macro, which works fine:

#ifndef NDEBUG

#define errorLog(fmt, ...) fprintf(stderr, "[ERROR %s: %d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)

#endif

Except if i try next line (which produce expected a ')' error):

const char* someMessage = "Message";
errorLog(someMessage);

But this one produce no errors:

errorLog("Message");

Right now i solve this like:

const char* someMessage = "Message";
errorLog("%s", someMessage);

How to change macro to work with single const char* param as well?

const char* someMessage = "Message";
errorLog(someMessage); //fprintf(stderr, someMessage)
Was it helpful?

Solution

As written, your errorLog requires a string literal for the first (fmt) argument, as it tries to use string concatenation, which only works with string literals. If you want a macro that can take any char *, not just a string literal, you have to use it directly, rather than pasting. You could use something like:

#define errorLog(...)   \
        (fprintf(stderr, "[ERROR %s: %d] ", __FUNCTION__, __LINE__),  \
         fprintf(stderr, __VA_ARGS__),  \
         fprintf(stderr, "\n"))

This will work for any char *, but will not have the same return value, if you care about that. This also has the advantage that it doesn't depend on the gcc , ## __VA_ARGS__ extension which may not work on other compilers.

If you want this to work properly in a multithreaded program, you might need:

#define errorLog(...)   \
        (flockfile(stderr),  \
         fprintf(stderr, "[ERROR %s: %d] ", __FUNCTION__, __LINE__),  \
         fprintf(stderr, __VA_ARGS__),  \
         fprintf(stderr, "\n"),  \
         funlockfile(stderr))

instead

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top