gpt4 book ai didi

C语言宏代码——#define with 2 '##'

转载 作者:太空狗 更新时间:2023-10-29 17:19:36 25 4
gpt4 key购买 nike

我最近遇到了这个问题,找不到解释的支持文档或数据。向我提出了这个问题,但对方不愿意分享答案。

#define BIT(A)       BIT_##A
#define PIN_0 0

“我们是否使用宏 BIT(PIN_0) 获取 BIT_0?如果没有,请进行必要的更正?”

我不知道上述问题的答案?

最佳答案

#define BIT(A) BIT_##A

意味着从原本是两个单独 的标记创建一个单个 标记。如果不使用 ##( token 连接运算符),您可能会想执行以下操作之一:

#define BIT(A) BIT_A
#define BIT(A) BIT_ A

第一个问题是,因为 BIT_A 已经是单个标记,所以将 A 与传递的参数匹配的尝试不会成功,您将得到文字扩展BIT_A,无论什么你用作参数:

BIT(42) -> BIT_A

第二个问题是,尽管 A 是一个单独的标记,因此被替换,但最终的扩展将不会 是一个单一的标记:

BIT(42) -> BIT_ 42

宏中的## 获取A 指定的,并将其附加到文字BIT_ 形成一个标记,例如,

BIT(7)    -> BIT_7
BIT(PIN0) -> BIT_PIN0, but see below if you want BIT_0

这在 C11 6.10.3.3 The ## operator 中有介绍:

... each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token.

The resulting token is available for further macro replacement.


现在,如果您想要一个将 BIT_ 和另一个已经计算过的宏 连接在一起的宏,成为一个单独的标记,您必须使用一些技巧来实现它在连接之前执行初始宏替换。

那是因为标准声明串联是在常规宏替换之前执行的,这就是为什么需要这种技巧的原因。你所拥有的问题:

#define PIN_0  0
#define BIT(A) BIT_##A

BIT(PIN0)## 扩展最初将生成单个 token BIT_PIN0 .现在,虽然这需要进一步的宏替换,但该单个 token 实际上没有宏替换,所以它保持原样。

要解决这个问题,您必须使用间接级别强制预处理器在 ## 之前进行常规宏替换:

#define CONCAT(x,y) x ## y
#define PIN0 0
#define BIT(A) CONCAT(BIT_,A)

上面显示的这一系列宏经历了多个阶段:

BIT(PIN0)
-> CONCAT(BIT_,PIN0)
-> CONCAT(BIT_,0)
-> BIT_0

关于C语言宏代码——#define with 2 '##',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32578135/

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