I would like to log the return value of a function. The problem is that the function might have many exit points and I don\'t want to add a log call before every one of them.
I don't think you can do that more nicely and easily. In this case I think the solution with least impact on the source is to use the preprocessor, but you shouldn't do it the way you do because it has surprices built in. Fx:
if( done )
RETURN(something);
expands to:
if( done )
Logger.log("function_name", something); return something;
which means that something
is sent to the log if done
is true, then something
is returned anyway.
To make the expansion fit into a single statement it's normally wrapped in a do { ... } while(0)
which would make that example log and return only if done
is true.
But there's still a surprise since the macro argument is expanded twice, consider the case where you write RETURN(something++);
then it will expand to Logger.log(__FUNCTION__, something++); return something++;
which means unfortunate side effects. This was a real problem in C, but not in C++. Here templates are handy:
template<typename T>
T const& log_and_return(char const* func, const T& value)
{
Logger.log(func, value);
return value;
}
#define RETURN(value) return log_and_return(__func__, value)
Note that it is called __func__
in the standard (an not __FUNCTION__
).