gpt4 book ai didi

C++11嵌套宏调用?

转载 作者:IT老高 更新时间:2023-10-28 22:30:24 37 4
gpt4 key购买 nike

它在 C++ std 16.3.4 中说:

The resulting preprocessing token sequence [from a macro invocation replacement] is rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.

If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced.

Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced.

These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.

什么是嵌套宏替换?

具体考虑:

#define f(x) 1 x
#define g(x) 2 x

g(f)(g)(3)

我会期待以下内容:

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,产生:

2 1 2 3

有什么想法吗?

更新:

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

#define A(x) B
#define B(x) A(x)

A(i)(j)

展开如下:

A(i)(j)
B(j)
A(j)

标准没有规定A(j)是否应该扩展为B。委员会决定以这种方式离开它,因为现实世界的程序不应该依赖于这种行为,所以保持 A(j) 不扩展并将 A(j) 扩展为B 被认为是一致的。

最佳答案

这解释了最初的意图,以及为什么没有在标准中添加关于此主题的说明:

http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#268


268. Macro name suppression in rescanned replacement text

Section: 16.3.4 [cpp.rescan]     Status: open     Submitter: Bjarne Stroustrup     Date: 18 Jan 2001

It is not clear from the Standard what the result of the following example should be:

#define NIL(xxx) xxx
#define G_0(arg) NIL(G_1)(arg)
#define G_1(arg) NIL(arg)
G_0(42)

The relevant text from the Standard is found in 16.3.4 [cpp.rescan] paragraph 2:

[snipped]

G0(42)的展开顺序如下:

G0(42)
NIL(G_1)(42)
G_1(42)
NIL(42)

问题是在此序列的最后一行中使用 NIL 是否符合引用文本下的不可替换条件。如果是,结果将是 NIL(42)。如果没有,结果将只是 42.

本文中J11委员会的初衷是结果应该是42,正如Dave Prosser提供的替换算法的原始伪代码描述所证明的那样,它的作者。然而,英文描述省略了伪代码的一些微妙之处,因此可以说对这种情况给出了错误的答案。

建议的分辨率(Mike Miller):[snipped]

2004 年 4 月 WG14 session 的笔记(来自 Tom Plum):

早在 1980 年代,几位 WG14 人员就明白,“不可替代”的措辞与产生伪代码的尝试之间存在细微差别。 委员会的决定是,“野外”的任何现实项目都不会冒险进入这一领域,并且试图减少不确定性是不值得冒改变实现或项目的一致性状态的风险。

关于C++11嵌套宏调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15583021/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com