首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++预处理标准行为

C++预处理标准行为
EN

Stack Overflow用户
提问于 2014-03-23 11:05:56
回答 2查看 601关注 0票数 15

我正在研究关于预处理器的确切行为的C++标准(我需要实现某种C++预处理程序)。根据我的理解,我所编的(以帮助我理解)的例子应该是有效的:

代码语言:javascript
复制
#define dds(x) f(x,
#define f(a,b) a+b
dds(eoe)
su)

我希望像宏调用dds(eoe)这样的第一个函数被f(eoe,替换(注意替换字符串中的逗号),当输入被重新屏蔽时,这个逗号被认为是f(eoe,su)

但是VC++2010的测试给了我这个结果(我告诉VC++输出预处理文件):

代码语言:javascript
复制
eoe+et_leoe+et_l
su)

这是违反直觉的,显然是不正确的。是VC++2010的错误还是我对C++标准的误解?特别是,在替换字符串的末尾加上逗号是否与我一样不正确?我对C++标准语法的理解是,任何preprocessing-token都是允许的。

编辑:

我没有GCC或其他版本的VC++。有人能帮我和这些编译器核实一下吗。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-23 12:16:48

据我所知,在标准的[cpp.subst/rescan]部分中,没有任何东西会使您的行为成为非法行为,clang和gcc将其扩展为eoe+su是正确的,而MSC (VisualC++)行为必须报告为bug。

我没能让它发挥作用,但我设法为您找到了一个丑陋的MSC解决方案,使用了各种变量--您可能会发现它有帮助,或者您可能没有,但无论如何,它是:

代码语言:javascript
复制
#define f(a,b) (a+b
#define dds(...) f(__VA_ARGS__)

它扩大为:

代码语言:javascript
复制
(eoe+
su)

当然,这对gcc和克朗来说是行不通的。

票数 2
EN

Stack Overflow用户

发布于 2014-03-23 11:44:06

嗯,我看到的问题是,预处理器执行以下操作

ddx(x)变成f(x,

然而,f(x,也被定义为f(a,b) ),所以f(x,扩展为x+垃圾)。

因此,ddx(x)最终转换为x+垃圾(因为您定义了f(smthing ) )。

您的dds( eoe )实际上扩展到a+b,其中a是eoe,b是et_l。无论出于什么原因,它都会做到两次。)

此场景是编译器特定的,这取决于预处理器如何选择处理定义的扩展。

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

https://stackoverflow.com/questions/22590006

复制
相关文章

相似问题

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