Макро функция не расширяется, как ожидалось - PullRequest
0 голосов
/ 04 октября 2019

РЕДАКТИРОВАТЬ возможная повторяющаяся ссылка не помогает решить проблему.

Ниже приведен минимально компилируемый код с комментариями, проблема в том, что макрос ERR_INFO вызывает проблемы с расширением HRESULT ˙параметр в функции макроса LOG_IF_FAILED

Я уверен, что проблема тривиальна, но отладка макросов - такой кошмар.

#define UNICODE
#include <Windows.h>
#include <comdef.h>
#include <iostream>
#include <cwchar>


void DebugLogTrace(PCTSTR format_string, ...)
{
    // implementation not important
}

// Writes a sprintf-formatted string to the logging file.
#define TRACE(...) DebugLogTrace(__VA_ARGS__)

#ifdef UNICODE
// Show only file name instead of full path wide version
#define FILENAME (std::wcsrchr(TEXT(__FILE__), L'\\') ? std::wcsrchr(TEXT(__FILE__), L'\\') + 1 : TEXT(__FILE__))

// Wide string function name
#define FUNCNAME __FUNCTIONW__

// boilerplate macro
#define ERR_INFO FILENAME, FUNCNAME, __LINE__

// Log HRESULTs if failed.
#define LOG_IF_FAILED(file_name, func_name, line, hr) if (FAILED(hr)) \
    { TRACE(TEXT("%s %s %i %s"), file_name, func_name, line, _com_error(hr).ErrorMessage()); }
#else

// ANSI versions here ...

#endif // UNICODE

int main()
{
    HRESULT hr = CoInitializeEx(nullptr,
        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    // Here hr is not inserted into expansion
    // ERR_INFO macro is causing problems somehow
    LOG_IF_FAILED(ERR_INFO, hr);

    // This works however
    LOG_IF_FAILED(FILENAME, FUNCNAME, __LINE__, hr);

    return 0;
}

1 Ответ

1 голос
/ 04 октября 2019

LOG_IF_FAILED(ERR_INFO, hr) должно вызывать что-то вроде:
error: macro "LOG_IF_FAILED" requires 4 arguments, but only 2 given.

Это может быть решено с помощью еще одного уровня косвенности.

Переименуйте LOG_IF_FAILED во что-тоиначе, скажем, LOG_IF_FAILED_.
Затем добавьте #define LOG_IF_FAILED(...) LOG_IF_FAILED_(__VA_ARGS__).

Редактировать:

По какой-то причине это не работает с препроцессором MSVC. Если вы используете MSVC, LOG_IF_FAILED должен быть определен как:

#define EMPTY
#define LOG_IF_FAILED(...) LOG_IF_FAILED_ EMPTY (__VA_ARGS__)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...