gpt4 book ai didi

c - 单个散列在类对象宏中的作用

转载 作者:太空狗 更新时间:2023-10-29 15:05:36 24 4
gpt4 key购买 nike

是否允许在类对象宏中使用 #,如果允许,会发生什么情况?

C 标准只定义了# 在类函数宏的宏中的行为。

示例代码:

#include <stdio.h>

#define A X#Y
#define B(X) #X
#define C(X) B(X)

int main()
{
printf(C(A) "\n");
}

gcc 输出 X#Y,表明它允许 # 出现并且不执行任何特殊处理。但是,由于 # 运算符的定义没有定义这种情况下的行为,它实际上是未定义的行为吗?

最佳答案

如您所见,# 仅在类似函数的宏中具有已定义的效果。 § 6.10.3.2/1(所有对该标准的引用均针对 C11 草案 (N1570))。要了解类对象宏中发生了什么,我们必须看看别处。

A preprocessing directive of the form

# define identifier replacement-list new-line

defines an object-like macro that causes each subsequent instance of the macro name to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive. [...]

§ 6.10.3/9

因此,唯一的问题是 # 是否允许出现在 replacement-list 中。如果是,它照常参与替换。

我们在§ 6.10/1 中找到语法:

replacement-list:
pp-tokens (opt.)

pp-tokens:
preprocessing-token
pp-tokens preprocessing-token

现在,# 是有效的 preprocessing-token 吗? § 6.4/1 说:

preprocessing-token:
header-name
identifier
pp-number
character-constant
string-literal
punctuator
each non-white-space character that cannot be one of the above

它肯定不是header-name(§ 6.4.7/1),它不允许出现在identifier 标记中( § 6.4.2.1/1),也不是 pp-number(基本上是允许格式的任何数字,§ 6.4.8/1 ),也不是 character-constant(例如 u'c'§ 6.4.4.4/1)或 string-文字(正是您所期望的,例如 L"String"§ 6.4.5/1)。

但是,它在§ 6.4.6/1 中被列为标点符号。因此,它被允许出现在类对象宏的 replacement-list 中,并且会被逐字复制。它现在需要重新扫描,如§ 6.10.3.4 中所述。让我们看看您的示例:

C(A) 将替换为 C(X#Y)#在这里没有特殊作用,因为它不在Creplacement-list中,而是它的参数。 C(X#Y)显然变成了B(X#Y)。然后通过 Breplacement-list 中的 # 运算符将 B 的参数转换为字符串文字, 产生 "X#Y"

因此,您没有未定义的行为。

关于c - 单个散列在类对象宏中的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31579541/

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