Использование макроса для назначения и проверки ошибок

Короткая история, что я хочу это поведение:

#if defined(DEBUG) || defined(_DEBUG)
#define CHECK_HRESULT(x)                                    \
{                                                           \
HRESULT hr = (x);                                       \
if (FAILED(hr))                                         \
{                                                       \
DXTrace(__FILE__, (DWORD)__LINE__, hr, L#x, true);  \
}                                                       \
}
#else
#define CHECK_HRESULT(x)    (x)
#endif

но я также хочу сохранить и вернуть значение HRESULT для проверки ошибок в бесплатных сборках. В общем, я хочу иметь возможность сделать что-то вроде:

HRESULT hr = CHECK_HRESULT(Some_Function_Call());

которая будет присваивать значение hr как для бесплатных, так и для проверочных сборок, но также будет отображать диалоговое окно, когда недопустимый HRESULT возвращается для проверочных сборок. Да, я знаю, что мог бы создать встроенную функцию, но тогда мне пришлось бы передать строку для L#x что означает, что я дважды копирую оператор в моем коде, чего я хотел бы избежать (также, та же проблема возникает, когда вы пытаетесь написать макрос, который просто принимает hr в качестве входа). Я также хотел бы избежать чего-то вроде:

#if defined(DEBUG) || defined(_DEBUG)
#define CHECK_HRESULT(x)    (x);                            \
{                                                           \
HRESULT hr = (x);                                       \
if (FAILED(hr))                                         \
{                                                       \
DXTrace(__FILE__, (DWORD)__LINE__, hr, L#x, true);  \
}                                                       \
}
#else
#define CHECK_HRESULT(x)    (x)
#endif

поскольку x может очень легко быть функцией, которая выделяет память или выполняет что-то важное, и вызов этой функции дважды вызовет серьезное нежелательное поведение, особенно между проверенными и бесплатными сборками. Кроме того, само собой разумеется, что я хотел бы избежать предположения о том, что уже есть HRESULT с именем hr … Я уже шел темным путем раньше. Я понимаю, что, вероятно, было бы безопасно назначить значение S_OK по умолчанию в проверенных сборках, так как программа, скорее всего, все равно будет аварийно завершать работу, но мне это кажется просто небрежным.

В любом случае, спасибо за помощь!

0

Решение

У gcc есть расширение, позволяющее блокировать полный код в выражениях, но я предполагаю, что вам это нужно для VC ++? В каком случае вы могли бы определить макрос «CHECK_ASSIGN_HRESULT (v, x)», который выполняет проверки, но также присваивает результат v?

0

Другие решения

Вы можете ввести вспомогательную функцию:

#if defined(DEBUG) || defined(_DEBUG)
inline static HRESULT _Do_CheckHResult(HRESULT hr, const wchar* text, const wchar* file, DWORD line)
{
if (FAILED(hr))
{
DXTrace(file, line, hr, text, true);
}
return hr;
}

#define CHECK_HRESULT(x) _Do_CheckHResult(x, L#x, __FILE__, (DWORD)__LINE__)
#else
#define CHECK_HRESULT(x)    (x)
#endif

(Я написал это из головы, вероятно, это должно работать с копированием, но я не проверял это).

3

По вопросам рекламы [email protected]