Visual C++和gcc之间的宏##连接运算符的差异

Flo*_*rck 5 gcc stringification visual-c++ c-preprocessor

我有一个这样的宏(不完全是,但功能相当):

#define STRUCTMEMBER(Member,Value) GlobalStructInstance. ## Member = Value
...
STRUCTMEMBER(Item,1);
Run Code Online (Sandbox Code Playgroud)

这在Visual C++中完美地工作,但是gcc 3.4.5(MingGW)会产生以下错误:

粘贴"." 并且"Item"不提供有效的预处理令牌

当我使用" - >"运算符时也会发生这种情况.我没有找到关于连接的提示,禁止使用这些运算符.

有没有人有想法?

Ste*_*sop 7

也许Visual C++将一些空间粘贴在一起以形成另一个空间.并不是说空格是令牌,而是允许你的代码工作.

object.member它不是一个标记,它是三个标记,因此您不需要使用标记粘贴来实现您描述的宏.只需删除'##'即可在任何地方使用.

[编辑:刚刚检查过,使用##形成非有效令牌的结果是未定义的.因此,据我所知,GCC被允许拒绝它,并且允许MSVC忽略它并且不执行粘贴.


Mic*_*urr 5

根据C标准,' ##'预处理运算符的结果必须是'预处理标记'或结果未定义(C99 6.10.3.3(3) - ##运算符).

预处理令牌列表是(C99 6.4(3) - 词汇元素):

标题名称,标识符,预处理数字,字符常量,字符串文字,标点符号以及不与其他预处理标记类别词汇匹配的单个非空白字符.

GCC让您知道您正在进入未定义的区域.MSVC默默地对未定义的结果感到满意(这是你非常希望发生的事情).

请注意,如果您还没有创建单个令牌,那么您不需要令牌粘贴运算符.一般来说(我确定可能有一两个例外),用空格分隔的2个令牌相当于2个不用空格分隔的令牌 - 如你的例子所示.