Короткая история, что я хочу это поведение:
#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
по умолчанию в проверенных сборках, так как программа, скорее всего, все равно будет аварийно завершать работу, но мне это кажется просто небрежным.
В любом случае, спасибо за помощь!
У gcc есть расширение, позволяющее блокировать полный код в выражениях, но я предполагаю, что вам это нужно для VC ++? В каком случае вы могли бы определить макрос «CHECK_ASSIGN_HRESULT (v, x)», который выполняет проверки, но также присваивает результат v?
Вы можете ввести вспомогательную функцию:
#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
(Я написал это из головы, вероятно, это должно работать с копированием, но я не проверял это).