2011-09-28 69 views
5

许多C++项目(例如,许多Boost库)“仅标题链接”。仅标题链接

这也可能在普通C?如何将源代码放入标题中?有没有关于它的网站?

+0

您的工作方式与C++中的完全相同。包含头文件是C预处理器功能。 – avakar

+0

但是你拥有所有这些静态函数和公共函数,我想这并不容易。 – Cartesius00

回答

11

执行摘要:您可以,但您不应该。

在编译之前,C和C++代码是预处理:所有头以递归方式“粘贴”到包含它们的源文件中。如果在标题中定义了一个函数,并且它包含在两个C文件中,那么每个目标文件中将会有两个副本(One Definition Rule违例)。

如果您的所有功能都标记为static,即在翻译单元外部不可见,则可以创建“仅标题”C库。但这也意味着您将获得包含头文件的每个翻译单元中的所有静态函数的副本。在C++中有一点不同:内联函数不是static,编译器发出的符号仍然可以被链接器看到,但链接器可以丢弃重复内容,而不是放弃(“弱”符号)。

除非是基于宏(例如queue(3)),否则在头文件中编写C代码并不是惯用的。在C++中,在头文件中保留代码的主要原因是模板,这可能会导致不同模板参数的代码实例化,这不适用于C.

+0

+1:涵盖了我想的所有基础。 –

4

您不链接标题。

在C++中,编写在头文件中已经比在单独编译的模块中更好的代码稍微容易一些,因为模板需要它。

但是,您也可以使用inline关键字作为函数,它存在于C和C++中。

// Won't cause redefinition link errors, because of 6.7.4/5 
inline void foo(void) { 
    // ... 
} 

[c99: 6.7.4/5:]inline功能 符声明的函数是一个内联函数功能说明符可能会多次出现 ;行为与仅出现一次的行为相同。 使函数成为内联函数表明对函数 的调用尽可能快。这些建议的有效程度是由实施定义的。

不过,对于数据对象,你有点卡住了。


- 排序的。
- C99肯定。 C89/C90我必须检查。

+0

您的意思是静态关键字?因为内联只是编译器的建议,可以完全忽略。 – Cartesius00

+0

@James:不,我的意思是“内联”。尽管'inline'只是一个提示,编译器不需要物理内联函数,它对函数链接的影响很明确,并且必须由实现来观察。否则,你怎么知道你的'inline'函数有什么联系? –

+0

哦,我明白了,C和C++不同,不是吗? – Cartesius00

4

加速使大量使用模板和模板元编程,你不能效仿(所有易)在C.

但你当然可以通过其声明和代码在C头文件,你#include但是这是欺骗不是一回事。我会说“当在罗马......”和程序C根据C惯例与图书馆。

+0

我发现“在罗马时......”是一个很好的答案。谢谢:) – Cartesius00

+0

很高兴能有所帮助。随意接受它,只要您在审查时仍将其视为最佳答案即可。 –

3

是的,这是完全可能的。在头文件中声明所有函数,或者全部为static,或者在项目中只使用一个编译单元(即只有一个c文件)。作为一个个人轶事,我知道很多物理学家坚持认为这种技术是编程C的唯一真正方法。这是有益的,因为它是穷人的版本-fwhole-program,即基于函数行为可能。这很实用,因为您不需要了解使用链接器标志。这是一个糟糕的主意,因为您的整个程序必须作为一个整体进行编译并重新编译每一个小改动。

就我个人而言,我建议让它成为或者至少与static一起用于少数功能。

+0

答案并没有用这种方法指出眩目的洞。 –

+0

@ TomalakGeret'kal:哪个明亮的洞? – thiton

+0

'static'给你每个TU的副本。真的,所有其他答案都提到了这些漏洞。 –