gpt4 book ai didi

c - 解析类函数的宏和参数

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

1) 在 C 中,您可以在以下代码段中编写类似函数的宏,如 example1:

#define first(a, b)   a
#define second(a, b) b

#define example1(x) splitting the tuple: [first x] and [second x]
example1((1, 2))

扩展为拆分元组:[1] 和 [2]。这是因为参数在 firstsecond 宏名称被识别之前展开。

2) 作为扩展,您还可以使用可变参数宏轻松地从参数中删除括号:

#define unparen(...)  __VA_ARGS__
#define example2(x) removing parentheses: unparen x
example2((1, 2))

扩展为 删除括号:1、2

3) 然而以下不起作用:

#define example3(x) splitting the tuple: [first(unparen x)] and [second(unparen x)]
example3((1, 2))

cpp 的错误如下:

test.c:12:16: error: macro "first" requires 2 arguments, but only 1 given
test.c:12:16: error: macro "second" requires 2 arguments, but only 1 given

也就是说,firstsecond 的括号内参数在 unparen 展开之前被吞噬。这似乎与第(1)点矛盾。就 C 标准中的宏扩展算法而言,这是如何工作的?如果允许这样做会破坏什么?

最佳答案

补充回答只是为了扩展算法:

the parenthesized arguments of first and second are gobbled before unparen is expanded. This seems to contradict point (1). How does this work in terms of the macro expansion algorithm in the C standard, and what would break if it were allowed?

这与第 (1) 点并不矛盾,因为步骤比 (1) 似乎预期的更明确 - 有三个步骤,而不是两个。

首先,收集每个参数的文本并将其分配给一个参数,而不对其执行任何宏扩展。

其次,在替换列表中用参数替换它们扩展的标记列表,在我们以线性方式处理替换列表时独立扩展参数。

第三,出现在替换列表中的任何宏都会根据相同的规则立即扩展,这意味着如果它们出现在在此步骤中识别的类函数宏的参数列表中,它们还没有扩展 - 它们被反馈到嵌套扩展的第一步。

所以要牢记的重要细节是所有参数扩展都发生在之后输入了类似函数的宏,这与相对于函数体评估参数的顺序相反在主要的 C 语言中,因此可能违反直觉。

所以回到(3),顺序是:

  1. example3进入

  2. x第一次展开代入*

  3. first 输入,由于参数不匹配而失败

  4. 忽略失败,afirst 中替换为 unparen (1, 2)

  5. 只有现在,在first的展开中,unparen可以进入

...等等。


* 在存在像 __COUNTER__ 这样的语言扩展时,参数的重用可以揭示实现细节,但在标准语言中,x 的扩展没有区别> 被缓存或重新评估

关于c - 解析类函数的宏和参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48440507/

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