我正在查看一个仅 header 的 C“库”:https://github.com/zserge/jsmn/blob/master/jsmn.h
据我所知,这段代码将被编译到.c文件包含jsmn.h
的每个目标文件中,浪费空间。
(该文件的函数定义位于#ifndef JSMN_HEADER
内,因此您可以通过定义 JSMN_HEADER 将其用作“传统”头文件。)
- 为什么它没有被写成“传统的”
.c
和.h
对? - 链接器是否足够聪明,能够在目标文件之间删除相同的函数定义?我预计会出现“重复符号”错误。
- 将代码放在 header 中会给 C 带来什么好处? (不是 C++。)
- 如果在导入之前使用
#define JSMN_HEADER
,从哪里获取函数定义? jsmn.h
仅包含 header 是一个我可以学习的聪明技巧吗?
最佳答案
header 会扩展为以下内容之一,具体取决于定义的宏:
- 没有宏 - 函数定义(公共(public)函数是非静态的,私有(private)函数是)。
JSMN_HEADER
— 函数声明(仅适用于公共(public)函数)。JSMN_STATIC
—静态
函数定义(适用于私有(private)和公共(public)函数)。
如果只有一个TU需要该库,则可以在(1)和(3)之间自由选择。
如果多个 TU 需要该库,则您需要 (1) 在其中一个 TU 中,并 (2) 在所有其他 TU 中。那么唯一“浪费”的就是跳过 (2) 的函数定义的预处理器时间,但这并不重要,因为它们是如此之小。
在这种情况下,尝试对所有 TU 使用 (1) 会导致“重复符号”链接器错误。尝试对所有 TU 使用 (3) 会默默地复制符号,这会造成浪费。
Why hasn't it been written as a "traditional" .c and .h pair?
为了方便分发和使用该库。
Is the linker clever enough to dedup function identical definitions between object files? I would have expected "duplicate symbol" errors.
它可能不够聪明,但也没有必要。
您需要定义宏,以便只有一个 TU 具有定义。
What advantage does putting code in headers give in C?
需要分发的源文件更少。
From where do you get the function definitions if you use
#define JSMN_HEADER
before importing?
来自您在包含 header 之前未定义此宏的其他 TU。
Is
jsmn.h
being header-only a clever trick, from which I can learn?
是的。
关于c - 仅 header C "libraries"不是浪费吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69593411/