Visual-C++ 之间宏 ## 连接运算符的差异 和海湾合作委员会
我有一个像这样的宏(不完全是,但功能相当等效):
#define STRUCTMEMBER(Member,Value) GlobalStructInstance. ## Member = Value
...
STRUCTMEMBER(Item,1);
这在 Visual C++ 中完美运行,但 gcc 3.4.5 (MingGW) 产生以下错误:
粘贴“.” 并且“Item”没有给出有效的预处理令牌
当我使用“->”时也会发生这种情况 操作员。 我没有找到有关串联的提示,也没有发现禁止使用这些运算符。
有人有主意吗?
I'm having a macro like this ( not exactly, but function is quite equivalent):
#define STRUCTMEMBER(Member,Value) GlobalStructInstance. ## Member = Value
...
STRUCTMEMBER(Item,1);
This works perfectly in Visual C++, but gcc 3.4.5 (MingGW) yield the following error:
pasting "." and "Item" does not give a valid preprocessing token
This also happens when I use the "->" operator. I didn't found hints on concatenation, that the usage of these operators is forbidden.
Does anyone have an idea ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
也许 Visual C++ 将几个空格粘贴在一起以形成另一个空格。 空格并不是令牌,但它可以让您的代码正常工作。
object.member
不是一个标记,它是三个标记,因此您不需要标记粘贴来实现您描述的宏。 只需删除“##”,它就可以在任何地方工作。[编辑:刚刚检查过,使用 ## 形成无效标记的结果是未定义的。 因此据我所知,GCC 可以拒绝它,MSVC 可以忽略它并且不执行粘贴。]
Maybe Visual C++ is pasting a couple of spaces together to make another space. Not that whitespaces are tokens, but it would allow your code to work.
object.member
is not a token, it's three tokens, so you don't need token-pasting to implement the macro you describe. Just remove the '##' and it should work everywhere.[Edit: just checked, and the result of using ## to form something that isn't a valid token is undefined. So GCC is allowed to reject it and MSVC is allowed to ignore it and perform no paste, as far as I can tell.]
根据 C 标准,“
##
”预处理运算符的结果必须是“预处理标记”,否则结果是未定义的(C99 6.10.3.3(3) - ## 运算符)。预处理标记的列表是(C99 6.4(3) - 词汇元素):
GCC 让您知道您正在进入未定义的领域。 MSVC 默默地对未定义的结果感到满意(这正是您非常期望发生的情况)。
请注意,如果您不创建单个令牌,则不需要令牌粘贴运算符。 一般来说(我确信可能有一两个例外),由空格分隔的 2 个标记相当于 2 个不由空格分隔的标记 - 正如您的示例中所示。
According to the C Standard, the result of the '
##
' preprocessing operator must be a 'preprocessing token' or the result is undefined (C99 6.10.3.3(3) - The ## operator).The list of preprocessing tokens is (C99 6.4(3) - Lexical elements):
GCC lets you know that you're entering undefined territory. MSVC is silently happy with the undefined result (that is what you'd pretty much expect to happen).
Note that if you're not creating a single token anyway, then you don't need the token pasting operator. Generally (I'm sure there's probably an exception or two), 2 tokens separated by whitespace is equivalent to 2 tokens not separated by whitespace - as in your example.
来自 gcc c 预处理器文档:
Structure.member 不是单个标记。
在这种情况下,您不需要使用 ##(标记串联)运算符。 您只需将其删除即可。 以下是在 Linux 上使用 gcc 4.2.4 测试的示例:
From the gcc c preprocessor docs:
structure.member is not a single token.
In this case you do not need to use the ## (token concatenation) operator. You can just remove it. Here is an example tested with gcc 4.2.4 on linux: