用于扩展C预处理器宏的不同扫描次数



下面这样的问题是一个简单的宏,然而,msvc和gnu/clang的编译行为是不同的,所以要在msvc中扩展宏a,你需要比gnu/clang多扫描一次,为什么会发生这种情况?

#include <stdio.h>
#define EMPTY()
#define DEFER_(X) X EMPTY()
#define DEFER1(...) __VA_ARGS__ DEFER_(EMPTY)()
#define DEFER(...) __VA_ARGS__ DEFER_(EMPTY)()
#define TO_STR(X) TO_STR_(X)
#define TO_STR_(X) #X
#define A() 123
#define EXPAND(...) __VA_ARGS__
#define EXPAND1(...) EXPAND(__VA_ARGS__)
#define EXPAND2(...) EXPAND1(__VA_ARGS__)
int main(void)
{
printf(TO_STR(EXPAND1(DEFER(A)()))"n");
}

除msvc外,godbolt上所有编译器的行为都与gnu相同。

默认情况下,MSVC不使用标准的C或c++规则进行预处理。使用交换机/Zc:preprocessor请求符合标准的预处理。您还可以使用/std:c17来要求总体上符合C标准,而不仅仅是在预处理中,尽管一致性可能不完全。

最新更新