简体   繁体   English

从头文件中提取所有声明的函数名到 boost.preprocessor

[英]Extract all declared function names from header into boost.preprocessor

I have a C header file containing various declarations of functions, enums, structs, etc, and I hope to extract all declared function names into a boost.preprocessor data structure for iteration, using only the C preprocessor.我有一个 C 头文件,其中包含函数、枚举、结构等的各种声明,我希望仅使用 C 预处理器将所有声明的函数名称提取到boost.preprocessor 数据结构中以进行迭代。

All function declarations have two fixed distinct macros around the return type, something like,所有函数声明在返回类型周围都有两个固定的不同宏,例如,

// my_header.h
FOO int * BAR f(long, double);
FOO void BAR g();

My goal is to somehow transform it into one of the above linked boost.preprocessor types, such as (f, g) or (f)(g) .我的目标是以某种方式将其转换为上述链接的boost.preprocessor类型之一,例如(f, g)(f)(g) I believe it is possible by cleverly defining FOO and BAR , but have not succeeded after trying to play around with boost.preprocessor and P99.我相信通过巧妙地定义FOOBAR是可能的,但是在尝试使用boost.preprocessor和 P99 之后没有成功。

I believe this task can only be done with the preprocessor as,我相信这个任务只能用预处理器来完成,因为,

  1. As a hard requirement, I need to stringify the function names as string literals later when iterating the list, so runtime string manipulation or existing C++ static reflection frameworks with template magic are out AFAIK.作为一项硬性要求,我需要稍后在迭代列表时将函数名称字符串化为字符串文字,因此运行时字符串操作或具有模板魔法的现有 C++ 静态反射框架已不适用 AFAIK。
  2. While it can be done with the help of other tools, they are either fragile (awk or grep as ad-hoc parsers) or overly complex for the task (LLVM/GCC plugin for something robust).虽然它可以在其他工具的帮助下完成,但它们要么很脆弱(awk 或 grep 作为临时解析器),要么对于任务来说过于复杂(LLVM/GCC 插件用于强大的东西)。 It is also a motivation to avoid external dependencies other than those strictly necessary ie a conforming C compiler.除了那些严格必要的(即符合标准的 C 编译器)之外,避免外部依赖也是一种动机。

I don't think this is going to work, due to limitations on where parentheses and commas need to occur.由于括号和逗号需要出现的位置的限制,我认为这不会起作用。

What you can do, though, is the opposite.但是,您可以做的恰恰相反。 You could make a Boost.PP sequence that contains the signatures in some structured form and use it to generate the declarations as you showed them.您可以制作一个 Boost.PP 序列,其中包含某种结构化形式的签名,并使用它来生成您展示的声明。 In the end, you have the representation you want as well as the compiler's view of the declarations.最后,您将获得所需的表示形式以及编译器对声明的看法。

After some closer look at the internals of preprocessor tricks, I believe this is theoretically impossible.在仔细研究了预处理器技巧的内部之后,我相信这在理论上是不可能的。 This answer is kind of a more detailed expansion on top of @sehe's nice answer.这个答案是在@sehe 的好答案之上的一种更详细的扩展。

The fundamental working principle of arbitrary preprocessor lists like those in boost.preprocessor is indirect recursion.boost.preprocessor中的任意预处理器列表的基本工作原理是间接递归。 As such, it requires a way to consume one argument and pass the remaining on.因此,它需要一种方法来使用一个参数并传递剩余的参数。 The only two ways for CPP are commas (which can separate arguments) and enclosing parentheses (which can invoke macros). CPP 仅有的两种方法是逗号(可以分隔参数)和括号(可以调用宏)。

In the case of f(int, long) , f is neither followed by a comma nor surrounded by a pair of parenthese, so there is no way for it to be separated from the following list by the preprocessor without knowing the name in advance.f(int, long)的情况下, f后面既没有逗号也没有被一对括号包围,因此在不知道名称的情况下,预处理器无法将其与以下列表分开。

It could have changed the game if there were a BAZ after f , but sadly there is not and I have no control over the said library header :(如果f之后有BAZ ,它可能会改变游戏规则,但遗憾的是没有,我无法控制上述库头:(

There are other issues, albeit not as fatal, such as the UB of having preprocessor directives within macro definition or arguments .还有其他问题,尽管不是那么致命,例如在宏定义参数中具有预处理器指令的 UB。

Perhaps someday it would become possible to leverage the reflection TS to get all declared function names within a namespace as a consteval compile-time list and then iterate it with something along the lines of constexpr for , all in a semantic and type-safe manner... who knows也许有一天,可以利用反射 TS 将命名空间中所有声明的函数名称作为consteval编译时列表,然后使用类似于constexpr for的内容对其进行迭代,所有这些都以语义和类型安全的方式进行。 .. 谁知道

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM