2014-11-06 37 views
1

我有一个宏,检查错误状态。如果有错误,它会记录结果并返回方法。VC C++宏执行/评估每次在宏中使用宏参数

CHECKHR_FAILED_RETURN(hr) if(FAILED(hr)){LOGHR_ERROR(hr); return hr;} 

宏被称为像这样:

CHECKHR_FAILED_RETURN(_recordingGraph->StopRecording(&currentFile)); 

然而,如果结果确实FAILED(hr),再次执行方法来执行LOGHR_ERROR(hr)。我明白了为什么我的StopRecording在出现错误的情况下被调用两次,所以我的问题是...

如何评估宏中参数的结果,但在同一个宏中多次使用它?

UPDATE:基于以下建议

,我改变了我的宏以下。

#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); 
+1

东西是一些东西,宏是邪恶的,做一个功能,别的东西(更严重的说明,我不知道这很容易实现,如果有的话) – Borgleader 2014-11-06 16:49:41

+0

你可以发布代码,我们有些人无法查看图像。 – Barry 2014-11-06 16:59:12

+0

这看起来像你试图用宏来检查错误。你可以考虑一个'try'-'catch'块。 – 2014-11-06 17:10:19

回答

1

正如一位评论者所说,在每个可能的地方都喜欢一个函数。在这种情况下,这是不可能的,因为你想在代码中嵌入return

您可以对宏内的临时变量进行赋值,并使用它来代替多次调用该参数。

#define CHECKHR_FAILED_RETURN(hr) do{ HRESULT hr2=hr; if(FAILED(hr2)) {LOGHR_ERROR(hr2); return hr2; }}while(false) 

do环是成语确保宏可以在if使用 - else就像一个函数调用。使用C++ 11及以后,您可以使用lambda表达式。

+0

我写下了这个,但是用“\”使事情变得更清晰。检查我的答案更新。 – 2014-11-06 21:32:23

+0

@PaulKnopf:'do'的大部分目的是能够写出'if(blahblah)MACRO(); else {stuff; }'。当宏以分号结尾时失败。因为这两个分号然后在'if'之后表示一个空语句,所以'else'变为断开连接。 – 2014-11-06 22:39:24