logging: Add preprocessor workaround for MSVC

Needed to fix errors like:

const Source &_LogSource(const Source &)': expects 1 arguments - 3 provided
const Source &_LogSource(const Source &)': expects 1 arguments - 3 provided

due to a compiler bug:

https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly/5134656#5134656

Example CI failure:

https://github.com/bitcoin/bitcoin/actions/runs/8072891468/job/22055528830?pr=29256
This commit is contained in:
Ryan Ofsky 2024-02-27 20:45:00 -05:00
parent 12d97dbdcb
commit 5db1958e60

View file

@ -299,18 +299,21 @@ void _LogFormat(LogFn&& log, Source&& source, util::ConstevalFormatString<sizeof
log(source, source.Format(fmt, args...));
}
//! Internal helper to return first arg in a __VA_ARGS__ pack.
#define _FirstArg(arg, ...) arg
//! Internal helper to return first arg in a __VA_ARGS__ pack. This could be
//! simplified to `#define _FirstArg(arg, ...) arg` if not for a preprocessor
//! bug in Visual C++.
#define _FirstArgImpl(arg, ...) arg
#define _FirstArg(args) _FirstArgImpl args
//! Internal helper to check level and log. Avoids evaluating arguments if not logging.
#define _LogPrint(level, ...) \
do { \
if (LogEnabled(_LogSource(_FirstArg(__VA_ARGS__)), (level))) { \
if (LogEnabled(_LogSource(_FirstArg((__VA_ARGS__))), (level))) { \
const auto& func = __func__; \
_LogFormat([&](auto&& source, auto&& message) { \
source.logger.LogPrintStr(message, func, __FILE__, \
__LINE__, source.category, (level)); \
}, _LogSource(_FirstArg(__VA_ARGS__)), __VA_ARGS__); \
}, _LogSource(_FirstArg((__VA_ARGS__))), __VA_ARGS__); \
} \
} while (0)