为什么MSVC预处理程序将令牌的连接方式与GCC和Clang不同?

问题描述 投票:3回答:1

最近,我遇到了MSVC的问题。这是它的一个最小示例。

#define NUMBERSIGNS(a,b) a##b
#define CONCAT(a,b) NUMBERSIGNS(a,b) 
#define AA
#define BB  
CONCAT(B, CONCAT(A, A B))

我在想什么:

由于##之前或之后的参数将不会被扩展,因此我需要一个NUMBERSIGNS(a,b)宏来包装##,并用CONCAT(a,b)对其进行调用,因此,这些参数在被连接之前被扩展。] >

[当CONCAT(B, CONCAT(A, A B))展开时,我希望内部的CONCAT(A, A B)展开为AA B,产生CONCAT(B, AA B)

然后我们将AA扩展为,然后得到CONCAT(B, B)(我猜MSVC没有执行此步骤,并且我不知道是否应该这样做)。

然后我们将BB重新扫描并扩展为

由gcc和clang预处理,代码产生空的,这是我想要的结果:


而MSVC提供:

BAA B

这是MSVC的错误还是我正在编写未定义的行为?

最近,我遇到了MSVC的问题。这是一个最小的例子。 #define NUMBERSIGNS(a,b)a ## b #define CONCAT(a,b)NUMBERSIGNS(a,b)#define AA #define BB CONCAT(B,CONCAT(A,AB))...

c visual-c++ c-preprocessor
1个回答
1
投票
C 2018 6.10.3.1 1指定宏参数替换:

确定了调用类似函数的宏的参数后,将进行参数替换。除非包含在其中的所有宏都被扩展,否则替换列表中的参数(除非在###预处理令牌之前或在##预处理令牌之后(请参见下文))被相应的参数替换。在被替换之前,每个参数的预处理令牌都被完全替换为宏,就好像它们构成了其余的预处理文件一样;没有其他预处理令牌可用。
© www.soinside.com 2019 - 2024. All rights reserved.