How to write a logging function or macro that can add the caller's name to the log output in C
I need a register function or a C macro that needs to work on Linux, that can take a format string and a list of arguments, and can add the name of the caller function to the output string.
Here's an example. Suppose the logging function (macro) is called smart_log. It looks like this:
smart_log(const char *fmt, ...)
The first argument to fmt is a format string, just like the format string in printf. The next fmt is a list of additional arguments to feed fmt.
Suppose a function called example_function calls smart_log like this:
void example_function() {
smart_log("try to output number %d\n", 1);
}
Then the log line looks like this:
[example_function]: try to output number 1
So the key point is that smart_log adds the caller function to the format string.
I'm not sure how to do this in C. I think a macro can be used to achieve this.
source to share
There is no portable way for a function to know its caller in C. But you're right, the macro works:
#define smart_log(...) ( printf("[%s]: ", __func__) , printf(__VA_ARGS__) )
__func__
defined (C99 / C11 6.4.2.2 s .1)
as if, immediately after opening the parenthesis of each function definition, the declaration
static const char
__func__
[] = " -";
where function -name is the name of the lexically enclosing function.
Thanks to Hagen von Eitzen for improving my initial attempt!
source to share
This is very system / compiler dependent, as the exact mapping to get the function name is very compiler dependent. For Visual C ++, you have to use a macro __FUNCTION__
to get the current function name at compile time.
To make sure you register the function name correctly without putting the macro in every call smart_log
, you can call the logging function through the macro so that the macro that gets the function name is evaluated in the correct context - if you just add the macro to the function name, you always get the name of your logging function ...
So instead of calling this:
smart_log("log message");
You are calling:
smart_log("log message");
Which in turn is defined as follows:
#define SMART_LOG(message) smart_log(__FUNCTION__, message)
This is due to the assumption that your log function takes a function name as the first parameter, so customize it.
source to share
Define macros - SMART_LOG - which transmits __FILE__
, __FUNCTION__
and __LINE__
in smart_log
as arguments. Then whenever you use smart_log
it will automatically provide the smart_log
caller location code. Note, however, which __FUNCTION__
is non-standard but available in GCC (and Visual C, so I'm in luck): fooobar.com/questions/53460 / ... ).
source to share