Reputation: 9786
I have a macro that checks an error state. If there is an error, it logs the result and returns out of the method.
CHECKHR_FAILED_RETURN(hr) if(FAILED(hr)){LOGHR_ERROR(hr); return hr;}
The macro is called like this:
CHECKHR_FAILED_RETURN(_recordingGraph->StopRecording(¤tFile));
However, if the result has indeed FAILED(hr)
, the method is executed again to perform the LOGHR_ERROR(hr)
. I see why my StopRecording is getting called twice in case of an error, so my question is...
How do you evaluate the result of a parameter in a macro, but use it multiple times within the same macro?
UPDATE:
Based on suggestions below, I changed my macros to the following.
#define CHECKHR_FAILED_RETURN(hr) do { \
HRESULT result = hr; \
if(FAILED(result)) \
{ \
LOGHR_ERROR(result); \
return result; \
} \
} while (false);
#define CHECKHR_FAILED(hr) do { \
HRESULT result = hr; \
if(FAILED(result)) \
{ \
LOGHR_ERROR(result); \
return true; \
} \
else \
{ \
return false; \
} \
} while (false);
Upvotes: 1
Views: 130
Reputation: 308392
As one commenter says, prefer a function to a macro in every place where it's possible. In this case it's not possible, since you want to embed a return
into the code.
You can do an assignment to a temporary variable within the macro and use it instead of calling the parameter multiple times.
#define CHECKHR_FAILED_RETURN(hr) do{ HRESULT hr2=hr; if(FAILED(hr2)) {LOGHR_ERROR(hr2); return hr2; }}while(false)
The do
loop is an idiom ensuring that the macro can be used in an if
-else
just like a function call. With C++11 and onwards you can alternatively use a lambda expression.
Upvotes: 1