记录:控制 C++ 宏展开顺序(MSVC)

278 阅读1分钟

先上代码:

这是有问题的写法:

#define __FLF__ __FILE__, __LINE__, __FUNCSIG__

#define __LOG(szFile, ulLine, szFunc, szFormat, ...) \
    printf("%s@%u %s: %s", szFile, ulLine, szFunc, szFormat, __VA_ARGS__)

#define MY_LOG_ERROR(szFormat, ...) \
    __LOG(__FLF__, szFormat, __VA_ARGS__)

这是修复后的:

#define EXPAND(...) __VA_ARGS__

#define __FLF__ __FILE__, __LINE__, __FUNCSIG__

#define __LOG(szFile, ulLine, szFunc, szFormat, ...) \
    printf("%s@%u %s: %s", szFile, ulLine, szFunc, szFormat, __VA_ARGS__)

#define MY_LOG_ERROR(szFormat, ...) \
    EXPAND(__LOG(__FLF__, szFormat, __VA_ARGS__))

解释:

  1. MSVC 默认是从外向里展开的。__FLF__ __VA_ARGS__ 会被当成 __LOG 的位置参数,展开出错。
  2. 使用 EXPAND() 的三层结构,推迟了中间层的展开,问题得到解决。

TODO:验证 GCC/Clang 的行为。