仅标题链接

发布于 2024-12-07 03:33:19 字数 106 浏览 0 评论 0原文

许多 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

雪化雨蝶 2024-12-14 03:33:19

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

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.

捶死心动 2024-12-14 03:33:19

您不链接标题。

在 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:] 使用内联函数声明的函数
说明符是一个内联函数可能会出现函数说明符
不止一次;行为与只出现一次相同。

使函数成为内联函数建议调用
功能尽可能快。这种程度
建议是否有效是由实现定义的。

不过,当涉及到数据对象时,您会有点陷入困境。


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++. 2

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

[c99: 6.7.4/5:] A function declared with an inline function
specifier is an inline function. The function specifier may appear
more than once; the behavior is the same as if it appeared only once.

Making a function an inline function suggests that calls to the
function be as fast as possible. The extent to which such
suggestions are effective is implementation-defined.

You'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.

何以畏孤独 2024-12-14 03:33:19

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.

紫﹏色ふ单纯 2024-12-14 03:33:19

是的,这很有可能。在标头中声明所有函数,并且全部声明为静态,或者在项目中仅使用单个编译单元(即仅单个 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文