在查看CPython源代码时,我发现了一个名为listobject.c.h的文件.我不确定这个文件扩展名".c.h"是什么.该文件混合了函数原型和函数定义.有没有理由将.c添加到扩展名中,而不是只将其设置为.h文件?
我在谷歌上找不到任何关于这个文件扩展名的信息,因为他们删除了搜索查询中的特殊字符,所以我得到了关于.ch文件的信息.
在查看CPython源代码时,我发现了一个名为listobject.c.h的文件.我不确定这个文件扩展名".c.h"是什么.该文件混合了函数原型和函数定义.有没有理由将.c添加到扩展名中,而不是只将其设置为.h文件?
我在谷歌上找不到任何关于这个文件扩展名的信息,因为他们删除了搜索查询中的特殊字符,所以我得到了关于.ch文件的信息.
它没有普遍适用的含义,但通常,它被用来暗示它是一个实现文件,由于构建系统的需要,它在另一个文件中是#include
-ed的.
普通的头文件提供原型和声明,通常只提供声明为inline
或static
的内容的实现(甚至static
也不受欢迎,除非使用链接时优化来消除其已编译版本的重复数据).提供其他类型的实现可能会在多个编译的目标文件中重复定义相同的可见实体,从而导致在链接时出现重复的问题.由于本例中的.c.h
文件打算在exactly个一个文件中#include
化(例如,longobject.c.h
只打算包括在父目录的longobject.c
中),因此#include
化它没有问题,因为它不会创建重复的定义.
CPython专门使用它们的原因是the Argument Clinic.这是一个工具,可以让他们为内置生成优化的参数解析代码,而不必执行以下任一操作:
printf
的解析API,这些API很方便,但效率较低作为一个额外的好处,当他们改进他们的解析框架和选项时(例如,当他们添加向量调用作为实现方法/函数的选项时),Argument Clinic可以在一个地方更新,并且好处立即在整个代码库中累积.
因为Argument Clinic在每次运行时都会从头开始重新生成文件,所以它们不能轻松地整合到手写的"真正的工作"实现函数中,而不会造成大量的代码混乱,并给提交补丁的人带来问题,因此他们将生成的代码分解到.c.h
个文件中,以避免类似的冲突.