Reputation: 2946
I have a macro for calling a function and logging that the call was made
#define LogHandle(message,function) {Log(message + #function); function;}
The function also returns if it was successful or not, i can use a member variable like
#define LogHandle(message,function) {Log(message + #function); m_lastLogHandleResult = function;}
Then in code do
LogHandle("Tried to do sometheing",Func())
if(m_lastLogHandleResult) {/* more code */}
but this approach would be quite difficult to thread-safe
ideally id want to do something like
#define LogHandle(message,function) bool result; {Log(message + #function); result = function;}
but this causes issues if i try to use this macro twice within a scope as it's re-defining a local
is it possible to explicitly redefine a local variable? like
new bool result;
Edit: As comments suggest could put each call to this function within a scope {}
, which is not a bad solution, but ideally i'd like to be able to not do this
Upvotes: 1
Views: 97
Reputation: 1
An example from my Bismon software:
#define LOCALRETURN_ATLIN_BIS_BM(Lin,Res) do { \
struct stackframe_stBM*prevfram_##Lin \
= _.__frame.stkfram_prev; \
ASSERT_BM (prevfram_##Lin \
&& ((typedhead_tyBM *)prevfram_##Lin)->htyp \
== typayl_StackFrame_BM); \
prevfram_##Lin->stkfram_callfun = NULL; \
return (value_tyBM)(Res); \
} while(0)
#define LOCALRETURN_ATLIN_BM(Lin,Res) LOCALRETURN_ATLIN_BIS_BM(Lin,Res)
#define LOCALRETURN_BM(Res) LOCALRETURN_ATLIN_BM(__LINE__,(Res))
I would use LOCALRETURN_BM(x)
and it gets expanded to something unique by GNU cpp using concatenation and sometimes stringizing.
RefPerSys has similar tricks at end of 2020, and you could use some better preprocessor like GPP.
You could also design your own C++ code generator, with inspiration from SWIG or Qt moc
. Tools like ANTLR or GNU bison are then helpful. You would configure your build automation tool (e.g. your Makefile
for GNU make). See also GNU autoconf and GNU m4.
With GNU cpp specifically, you can use not only __LINE__
but also __COUNTER__
See also this related answer that you could generalize to emission of C++ code. Your C++ code generator might even emit #line
directives.
Upvotes: 1
Reputation: 409176
I would implement it using a combination of macros and functions.
A macro so we can get the function "name", which calls a function passing the "name" and which returns the result to be tested.
Perhaps something like this:
#define LogHandle(message, function, ...) LogHandleHelper(message, function, #function, __VA_ARGS__)
template<typename R, typename F, typename... A>
R LogHandleHelper(std::string const& message, F function, std::string function_name, A&&... arguments)
{
Log(message + function_name);
return function(std::forward<A>(arguments)...);
}
Could then be used as:
if (LogHandle("Tried to do sometheing", Func))
{
// Special case code here...
}
[Note: Untested. might need tweaks to get it working]
Upvotes: 3