首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC与VC++预处理器的意外行为

GCC与VC++预处理器的意外行为
EN

Stack Overflow用户
提问于 2014-04-02 09:21:26
回答 2查看 177关注 0票数 1

我正在努力理解C++标准的预处理要求。我创建的一个有点棘手的例子在GCC和VC++2010中得到了令人惊讶的结果:

代码语言:javascript
复制
#define a(x,y) x##y
#define tzsW kka
a(t,zs  )W

GCC产量:

代码语言:javascript
复制
tzs W

注意W之前添加的额外空间。

VC++2010产量:

代码语言:javascript
复制
tzsW

注在W之前没有添加空格,但是标识符没有进一步展开。我扫描了C++03标准,找不到任何东西说我们应该阻止创建一个新的标识符(tzsW),就像gcc一样。任何事情都不能阻止这个新的标识符进一步扩展(VC++行为)。

为什么GCC和VC++2010不喜欢新的标识符?

编辑

如果使用了另一个宏调用,例如

代码语言:javascript
复制
a(t,zs  )[]

gcc产量:

代码语言:javascript
复制
tzs[]

请注意,没有添加任何空格,显示gcc故意为我以前的案例添加空间。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-02 09:36:04

预处理程序的输出是令牌,而不是纯文本。除非使用令牌粘贴运算符,否则通常不会在预处理中组合令牌。

当您查看预处理步骤的输出时,必须将标记转换为文本。gcc插入了这个空间,这样你就不会误以为tzsW是一个单一的标记。在tzs[情况下,它不需要这样做,因为[不是一个有效的标识符,所以没有混淆。

这两个编译器都正确地不将tzsW视为要重新展开的单个令牌。

请注意,可视化C++文档承认,与编译原始源相比,编译预处理程序的输出可能会产生不同且不正确的输出,因为在将预处理输出转换为文本时,它们不会插入空格来分隔令牌。在正常操作中,当预处理器输出直接传递到编译器的下一阶段时,不会发生这种情况。

票数 4
EN

Stack Overflow用户

发布于 2014-04-02 09:35:22

  1. 空间还是没有空间? 我没有在标准中找到参考,但是这篇文章讨论了这个问题。简而言之,很难决定你是否想要那个空间.
  2. kka代替kka? 见标准16.3.4: 替换列表中的所有参数被替换后,生成的预处理令牌序列将与源文件的所有后续预处理令牌重新包装,以便替换更多的宏名称。

这表明VC的行为在这里是不正确的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22806882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档