GCC和VC ++预处理器的意外行为 [英] Unexpected Behaviour of GCC and VC++ Preprocessor

查看:170
本文介绍了GCC和VC ++预处理器的意外行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解C ++标准预处理器的要求。我创建的一个有点棘手的例子在GCC和VC ++ 2010有惊人的结果:

  #define a(x,y) x ## y 
#define tzsW kka
a(t,zs)W

GCC产量:

  tzs W 

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



VC ++ 2010产生:

  tzsW 

请注意,在W之前没有添加空格,标识符不进一步扩展。我扫描了C ++ 03标准,没有找到任何东西,我们应该阻止一个新的标识符( tzsW )被创建为gcc。没有什么是阻止这个新的标识符进一步宏扩展(VC ++行为)。



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



EDIT



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

  a(t,zs)[] 



  tzs [] 

注意没有添加空格,显示gcc故意为我的前一个案例添加空间。

解决方案

是令牌,不是纯文本。除非您使用令牌粘贴操作符,否则令牌通常不会在预处理中组合。



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



两个编译器都不能将 tzsW 作为单个令牌进行重新展开。 / p>

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


I am trying to understand the C++ standard preprocessor requirement. A little bit tricky example I created has surprising results in GCC and VC++2010:

#define a(x,y) x##y
#define tzsW kka
a(t,zs  )W

GCC yields:

tzs W

Note the extra space added before W.

VC++2010 yields:

tzsW

Note there is no space added before W but the identifier is not further expanded. I scanned through the C++03 standard and cannot find anything saying we should prevent a new identifier (tzsW) from being created as in gcc. And nothing is about preventing this new identifier from further macro expanded (VC++ behaviour).

Why GCC and VC++2010 don't like the new identifier?

EDIT

if another macro invocation used, e.g.

a(t,zs  )[]

gcc yields:

tzs[]

Note no space added, showing gcc deliberately adds space to my previous case.

解决方案

The output of the preprocessor is tokens, not plain text. Unless you use the token pasting operator, tokens are not normally combined in preprocessing.

When you view the output of the preprocessing step, you have to convert the tokens to text. gcc inserts the space so you are not mislead into thinking that tzsW is a single token. It doesn't need to do this in the tzs[ case as [ isn't a valid identifier character so there's no confusion.

Both compilers are correct in not treating tzsW as a single token to be re-expanded.

Note that the Visual C++ documentation acknowledges that compiling the output of the preprocessor may produce different and incorrect output compared with compiling the original source due to the fact that they don't insert whitespace to delimit tokens when converting the preprocessed output to text. This doesn't happen when the preprocessor output is passed straight to the next stage of the compiler in normal operation.

这篇关于GCC和VC ++预处理器的意外行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆