首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11嵌套宏调用?

C++11嵌套宏调用?
EN

Stack Overflow用户
提问于 2013-03-23 03:28:23
回答 3查看 4.7K关注 0票数 16

它在C++性病16.3.4中说:

宏调用替换产生的预处理令牌序列与源文件的所有后续预处理令牌一起重新包装,以获得更多要替换的宏名称。 如果在此替换列表扫描过程中找到要替换的宏的名称(不包括源文件的其他预处理令牌),则不会替换它。 此外,如果任何嵌套的替换遇到要替换的宏的名称,则不会替换它。 这些未被替换的宏名称预处理令牌不再可供进一步替换,即使它们稍后(重新)在否则会被替换的宏名称预处理令牌的上下文中进行检查。

嵌套宏替换究竟是什么?

具体考虑:

代码语言:javascript
复制
#define f(x) 1 x
#define g(x) 2 x

g(f)(g)(3)

我本以为会有以下情况:

代码语言:javascript
复制
g(f)(g)(3)    <-- first replacement of g, ok
2 f(g)(3)     <-- nested replacement of f, ok
2 1 g(3)      <-- second nested replacement of g, don't replace, stop

然而gcc却出人意料地进行了g的第二次替换,生产:

代码语言:javascript
复制
2 1 2 3

有什么想法吗?

更新:

经过大量的研究,让我用一个简单的例子来澄清这个问题:

代码语言:javascript
复制
#define A(x) B
#define B(x) A(x)

A(i)(j)

这一范围扩大如下:

代码语言:javascript
复制
A(i)(j)
B(j)
A(j)

该标准没有指定是否应该将A(j)扩展为B。委员会决定以这种方式放弃它,因为现实世界的程序不需要依赖于这种行为,所以不管是不扩展A(j)还是将A(j)扩展到B都被认为是一致的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-28 00:45:11

这就解释了最初的意图,以及为什么标准中没有对这一问题作出任何澄清:

active.html#268

  1. 重新屏蔽替换文本中的宏名称抑制 :16.3.4 cpp.rescan Status:open Bjarne Submitter:Bjarne Stroustrup Date:2001年1月18日 “标准”中不清楚以下示例的结果: #定义NIL( xxx ) xxx# G_0(arg) NIL(G_1)(arg) # G_1(arg) NIL(arg) G_0(42) “标准”的有关案文载于16.3.4 cpp.rescan第2段: G0(42)的扩展顺序如下: G0(42) 0(G_1)(42) G_1(42) 0(42) 问题是,在这个序列的最后一行中使用NIL是否符合引用文本中不可替换的条件。如果是的话,结果将是NIL(42)。如果没有,结果将是简单的42 本文中的42**,委员会的最初意图是,其作者戴夫·普罗瑟提供的替换算法的原始伪代码描述证明了这一结果应该是 J11。然而,英文描述忽略了伪代码的一些微妙之处,因此可以说给出了一个错误的答案。 建议的分辨率(迈克·米勒):剪短 2004年4月WG14会议记录(通过Tom ): 早在20世纪80年代,一些WG14人士就认识到,“非替代”语句与试图生成伪代码的尝试之间存在着微小的差异。委员会的决定是,“在野外”不会有任何现实的项目进入这一领域,试图减少不确定性不值得冒改变实现或程序的一致性状态的风险。
票数 6
EN

Stack Overflow用户

发布于 2013-03-23 07:43:32

g(x)总是被2 x取代。在g的第二个嵌套替换中,使用x=3调用x=3,从而生成结果2 3。我的理解是,编译器不会用它的值替换宏,以防产生无限循环:

代码语言:javascript
复制
#define g( x ) f( x )
#define f( x ) g( x )

g( 1 ) -- > f( 1 ) --> stop 
票数 0
EN

Stack Overflow用户

发布于 2013-05-22 08:26:26

因为它提到了“(不包括源文件的其他预处理令牌)。g的第一个替代者只看到f。现在,f有资格用从文件的其余部分获取的预处理令牌来替换,但是程序没有记录f是由g生成的。f(g)的替换会产生一个同样不受递归污染的g

嵌套替换是由另一个替换包含的替换,而不是其令牌来自另一个替换的替换。根据后一种定义,替代者可能有几个相互排斥的嵌套父母。

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

https://stackoverflow.com/questions/15583021

复制
相关文章

相似问题

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