标签: token-pasting-operator

说明 C 预处理器中 # 和 ## 的未指定相对计算顺序的示例

关于已接受答案的一些评论位于本问题帖子的底部。

\n
\n

问题陈述

\n

根据C标准(C17草案,6.10.3.2\xc2\xb62):

\n
\n

#[the]和运算符的求值顺序##未指定。

\n
\n

我正在寻找一个示例,其中此评估顺序很重要,并且没有其他未定义行为的实例并且没有错误。

\n

在花了一些时间处理这个问题之后,我怀疑以下方法可能有效:

\n
#define PRECEDENCETEST(a, b, c)  # a ## b\n\nPRECEDENCETEST(c, , d)\n
Run Code Online (Sandbox Code Playgroud)\n

(请注意,预处理器可以按如下方式运行:cppgcc -E(GCC),cl /E (MSVC);请参阅下面的可编译虚拟示例。另请注意,空宏参数仅自 C99 起才合法。)

\n

我的问题:根据 C 标准,这实际上可以作为一个相对评估顺序#和产生合法输出的示例吗?##正如我在本文底部所解释的那样,如果我理解正确的话,答案可能取决于标准是否允许在之后使用令牌#与最初指定的令牌不同。

\n

如果答案是“是(因为......)”,那么我们就找到了一个例子!如果答案是“不,你的例子不起作用(因为......)”,那么我稍后会想办法征求更好的例子。

\n

(请注意,该标准不要求编译器对#和具有绝对相对评估顺序##运算符具有绝对相对的求值顺序。顺序可以是:从左到右、从右到左、遵循某些其他逻辑或完全随机。)

\n

文档

\n

较旧的 GCC 文档(似乎最高版本为 6.5)指出

\n
\n

##该标准没有指定 \xe2\x80\x98 \xe2\x80\x99 运算符链的计算顺序,也没有#指定 \xe2\x80\x98 \xe2\x80\x99 …

c operator-precedence language-lawyer c-preprocessor token-pasting-operator

6
推荐指数
1
解决办法
215
查看次数

为什么预处理器禁止宏粘贴奇怪的标记

我正在编写自己的基于 GCC 的 C 预处理器。到目前为止,它几乎是相同的,但我认为多余的是对由 virue of 连接的令牌执行任何形式的检查##。所以在我的预处理器手册中,我写了这个:

3.5 串联

...

GCC 禁止连接两个互不兼容的预处理标记,例如“x”和“+”(以任何顺序)。这将导致以下错误:“粘贴“x”和“+”没有给出有效的预处理标记”但是对于这个预处理器来说不是真的- 连接可能发生在任何标记之间。

我的推理很简单,如果它扩展为无效代码,那么编译器将产生错误,因此我不必显式处理此类情况,从而使预处理器变慢并增加代码复杂性。如果它产生了一个有效的代码,那么这个限制移除只会使它更灵活(尽管可能在极少数情况下)。

所以我想问一下,为什么这个错误真的发生了,为什么这个限制实际上被应用了,如果我在我的预处理器中忽略它是一种真正的犯罪吗?

c concatenation c-preprocessor token-pasting-operator

1
推荐指数
1
解决办法
90
查看次数