许多C ++项目(例如许多Boost
库)都是“仅限标题链接”。
这是否也可以在普通C
中使用?如何将源代码放入标题?有没有关于它的网站?
答案 0 :(得分:11)
执行摘要:您可以,但不应该。
C和C ++代码在编译之前是预处理:所有标题都以递归方式“粘贴”到包含它们的源文件中。如果在标题中定义一个函数并且它包含在两个C文件中,则每个目标文件中最终会有两个副本(One Definition Rule违规)。
如果所有功能都标记为static
,即在翻译单元外部不可见,则可以创建“仅标题”C库。但这也意味着您将获得包含头文件的每个翻译单元中所有静态函数的副本。
在C ++中有点不同:内联函数不是static
,编译器发出的符号仍然可以被链接器看到,但链接器可以丢弃重复,而不是放弃(“弱”符号)
在标头中编写C代码并不是惯用的,除非它基于宏(例如queue(3)
)。在C ++中,将代码保留在头文件中的主要原因是模板,这可能导致不同模板参数的代码实例化,这不适用于C.
答案 1 :(得分:4)
您没有链接标题。
在C ++中,编写已在标题中比在单独编译的模块中更好的代码更容易,因为模板需要它。 1
但是你也可以使用inline
关键字来存在C和C ++中的函数。 2
// Won't cause redefinition link errors, because of 6.7.4/5
inline void foo(void) {
// ...
}
[c99: 6.7.4/5:]
使用inline
函数声明的函数 说明符是内联函数。 可能会出现功能说明符 不止一次;行为与只出现一次的行为相同。 使函数成为内联函数表明调用了函数 功能尽可能快。这种程度的程度 建议是有效的是实施定义。
但是,在涉及数据对象方面,你有点困惑。
1 - 排序。
2 - 肯定是C99。 C89 / C90我得检查一下。
答案 2 :(得分:4)
Boost使用大量使用模板和模板元编程,你无法在C中模拟(很容易)。
但你当然可以通过在#include
的C标题中使用声明和代码来作弊,但这不是一回事。我会说“在罗马时......”和程序C按照C约定与库。
答案 3 :(得分:3)
是的,很有可能。在标题中声明所有函数,全部为static
,或者只在项目中使用单个编译单元(即只有一个c文件)。
作为一个个人轶事,我知道很多物理学家坚持认为这种技术是编程C的唯一真正方法。这是有益的,因为它是穷人的版本-fwhole-program
,即基于的优化功能行为的知识可能。这很实用,因为您不需要了解使用链接器标志。这是一个坏主意,因为您的整个程序必须作为一个整体进行编译,并在每次微小更改时重新编译。
就我个人而言,我建议只允许static
或仅使用{{1}}来完成一些功能。