仅标题链接
许多 C++ 项目(例如许多 Boost
库)都是“仅标头链接”。
这在普通的C
中也可能吗?如何将源代码放入标题中?有相关网站吗?
Many C++ projects (e.g. many Boost
libraries) are "header-only linked".
Is this possible also in plain C
? How to put the source code into headers? Are there any sites about it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
执行摘要:可以,但不应该。
C 和 C++ 代码在编译之前经过预处理:所有标头都“粘贴”到包含它们的源文件中,递归地。如果您在标头中定义了一个函数,并且该函数包含在两个 C 文件中,则每个目标文件中最终都会有两个副本(一个违反定义规则)。
如果所有函数都标记为静态(即在翻译单元外部不可见),则可以创建“仅标头”C 库。但这也意味着您将获得包含头文件的每个翻译单元中所有静态函数的副本。
在 C++ 中有点不同:内联函数不是静态的,编译器发出的符号仍然对链接器可见,但链接器可以丢弃重复项,而不是放弃(“弱”符号) 。
在头文件中编写 C 代码并不符合习惯,除非它基于宏(例如
queue(3)
)。在C++中,将代码保留在头文件中的主要原因是模板,这可能会导致代码实例化为不同的模板参数,这不适用于C。Executive summary: You can, but you shouldn't.
C and C++ code is preprocessed before it's compiled: all headers are "pasted" into the source files that include them, recursively. If you define a function in a header and it is included by two C files, you will end up with two copies in each object file (One Definition Rule violation).
You can create "header-only" C libraries if all your functions are marked as
static
, that is, not visible outside the translation unit. But it also means you will get a copy of all the static functions in each translation unit that includes the header file.It is a bit different in C++: inline functions are not
static
, symbols emitted by the compiler are still visible by the linker, but the linker can discard duplicates, rather than giving up ("weak" symbols).It's not idiomatic to write C code in the headers, unless it's based on macros (e.g.
queue(3)
). In C++, the main reason to keep code in the headers are templates, which may result in code instantiation for different template parameters, which is not applicable to C.您不链接标题。
在 C++ 中,编写在标头中已经比在单独编译的模块中更好的代码稍微容易一些,因为模板需要它。 1
但是您也可以对函数使用
inline
关键字,该关键字存在于 C 和 C++ 中。 2不过,当涉及到数据对象时,您会有点陷入困境。
1 - 有点。
2 - 当然是C99。 C89/C90 我得检查一下。
You do not link headers.
In C++ it's slightly easier to write code that's already better-off in headers than in separately-compiled modules because templates require it. 1
But you can also use the
inline
keyword for functions, which exists in C as well as C++. 2You're a bit stuck when it comes to data objects, though.
1 - Sort of.
2 - C99 for sure. C89/C90 I'd have to check.
Boost 大量使用模板和模板元编程,您无法在 C 中模拟(非常容易)。
但是您当然可以通过在 C 头文件中添加声明和代码来作弊,您
#include
但这是不是同一件事。我会说“在罗马时...”并按照 C 约定与库进行 C 编程。Boost makes heavy use templates and template meta-programming which you cannot emulate (all that easily) in C.
But you can of course cheat by having declarations and code in C headers which you
#include
but that is not the same thing. I'd say "When in Rome..." and program C as per C conventions with libraries.是的,这很有可能。在标头中声明所有函数,并且全部声明为
静态
,或者在项目中仅使用单个编译单元(即仅单个 c 文件)。作为个人轶事,我认识很多物理学家,他们坚持认为这种技术是 C 语言编程的唯一真正方法。它是有益的,因为它是穷人版本的
-fwhole-program
,即基于函数行为知识的优化成为可能。它很实用,因为您不需要了解如何使用链接器标志。这是一个坏主意,因为您的整个程序必须作为一个整体进行编译,并针对每个微小的更改重新编译。就我个人而言,我建议仅对少数功能保留它或至少使用
static
。Yes, it is quite possible. Declare all functions in headers and either all as
static
or just use a single compilation unit (i.e. only a single c file) in your projects.As a personal anecdote, I know quite a number of physicists who insist that this technique is the only true way to program C. It is beneficial because it's the poor man's version of
-fwhole-program
, i.e. makes optimizations based on the knowledge of function behaviour possible. It is practical because you don't need to learn about using the linker flags. It is a bad idea because your whole program must be compiled as a whole and recompiled with each minor change.Personally, I'd recommend to let it be or at least go with
static
for only a few functions.