0

EDIT possible duplicate link doesn't help resolve the issue.

Bellow is a minimum compilable code with comments, the problem is that ERR_INFO macro is causing troubles expanding HRESULT˙paramater in macro function LOG_IF_FAILED

I'm sure the problem is trivial but debugging macros is such a nightmare.

#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;
}
metablaster
  • 1,958
  • 12
  • 26
  • 1
    `LOG_IF_FAILED` takes 4 parameters but you are only supplying 2? – Alan Birtles Oct 04 '19 at 11:43
  • @AlanBirtles the first parameter is a macro that should expand into 3 paramaters. resulting in 4 parameters, that works except 4th parameter is ignored. – metablaster Oct 04 '19 at 11:45
  • 1
    Macros don't work that way I'm afraid – Alan Birtles Oct 04 '19 at 11:45
  • @AlanBirtles I see in tooltip in VS that `ERR_INFO` macro is expanded into 3 parameters, just 4th one `HRESULT` isn't expanded. have other of similar macros and they work. – metablaster Oct 04 '19 at 11:48
  • Possible duplicate of [Passing macro arguments by macro](https://stackoverflow.com/questions/34356877/passing-macro-arguments-by-macro) – Alan Birtles Oct 04 '19 at 11:48
  • @AlanBirtles thanks but answer posted in link doesn't resolve the problem. – metablaster Oct 04 '19 at 11:52
  • Is this related to your other recent question? https://stackoverflow.com/questions/58213233/warning-c6031-return-value-ignored-in-macro-expansion – Adrian Mole Oct 04 '19 at 12:41
  • @Adrian yes it is but I implemented the `ERR_INFO` boilerplate macro since then and stumbled upon new problem unrelated to this question. question in the link works if all the arguments are passed. – metablaster Oct 04 '19 at 12:44

1 Answers1

1

LOG_IF_FAILED(ERR_INFO, hr) should cause something along the lines of:
error: macro "LOG_IF_FAILED" requires 4 arguments, but only 2 given.

This can be solved with one more level of indirection.

Rename LOG_IF_FAILED to something else, let's say LOG_IF_FAILED_.
Then add #define LOG_IF_FAILED(...) LOG_IF_FAILED_(__VA_ARGS__).

Edit:

This doesn't work with MSVC preprocessor for some reason. If you're using MSVC, LOG_IF_FAILED should be defined as:

#define EMPTY
#define LOG_IF_FAILED(...) LOG_IF_FAILED_ EMPTY (__VA_ARGS__)
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • I just tried that and now none of the 2 macros in `main` work. – metablaster Oct 04 '19 at 11:51
  • you haxor! that indeed works, thanks a lot! can you explain how this works, what is the trick? and can we conclude that MSVC preprocessor is going against the standard? – metablaster Oct 04 '19 at 12:15
  • oh I see, msvc doesn't expand `__VA_ARGS__` your solution is the same as `#define EXPAND(x) x` `#define LOG_IF_FAILED(...) LOG_IF_FAILED_ EXPAND((__VA_ARGS__))` – metablaster Oct 04 '19 at 12:20
  • 1
    https://stackoverflow.com/questions/35210637/macro-expansion-argument-with-commas – Santosh Dhanawade Oct 04 '19 at 12:20
  • @santoshdhanawade thanks i understand the problem now, just one more reason why should I hate microsoft. – metablaster Oct 04 '19 at 12:27
  • @metablaster If you decide you hate microsoft, you can switch to MinGW. :P – HolyBlackCat Oct 04 '19 at 12:42
  • @HolyBlackCat the is no match for Visual Studio which only works with msvc compiler, but I'm already considering to have GCC + codeblocks as a separate tool just to test my code against the standard. – metablaster Oct 04 '19 at 12:54