Sne*_*tel -2 c c++ language-lawyer c-preprocessor variadic-macros
与例如 C++ 的可变参数模板相比,CPP(C/C++ 预处理器;为简单起见,我将在本问题中将其视为一种单独的语言)中的可变参数宏非常有限。本质上,可变参数宏只是带有参数的宏,其参数允许包含逗号。这没有提供计算参数、一个接一个操作参数等的直接方法。这些事情是可能的,但需要精心设计、令人困惑且编译缓慢的技巧,例如本问题中描述的技巧。唯一可以直接处理的事情VA_ARGS就是将它们传递给可变参数函数。
我的问题是,他们为什么要这样设计?在像 CPP 这样的任何纯函数式语言中,列表的标准方法是 cons 样式的模式匹配:处理列表的第一个参数并递归其余部分,并为空列表设置基本情况。标准委员会成员应该非常熟悉这种方法。
为什么 CPP 的可变参数宏没有采用这样的方法?可变参数宏是否只是一种包装可变参数函数的方法,这样就不需要对参数列表进行操作?是否存在一些潜在的问题使得允许可变参数宏递归变得不切实际?或者...?
注意:我不是在寻找“因为人们不应该想要可变参数宏”形式的答案/评论。boost.preprocessor 之类的东西的存在表明,理性的人希望以非平凡的方式使用预处理器。也不寻求关于为什么其他设计是一个好/坏主意的个人意见。我试图找出当时的实际推理。
从 C 继承到 C++ 的可变宏。
克莱夫·费瑟( Clive Feather)撰写了将可变参数宏添加到 C 的论文。
论文 N580: Varargs for Function-like Macros指出:
该提议允许宏的作者声明它采用可变数量的参数,并整体替换尾随参数。
[...]
有可能提供更多的设施,但这已留给进一步的建议。
一个问题是是否应该允许零实际参数匹配尾随参数。已决定不允许这样做,因为这更适合单独提出的另一个提案。
所以计划是添加最需要的功能(一个可用于填充 printf 调用的宏),并为以后的论文留下进一步的扩展。
在 C++ 中,宏是二等公民。C++ 很少使用新的宏语法或功能进行创新,而是想出无需宏即可解决问题的方法。
C没有进一步创新。
添加到 C 中的实际 vararg 宏来自从那篇论文派生的论文,但那篇论文在这一决定背后有着最清晰的动机文本。