c - 仅 header C "libraries"不是浪费吗?

标签 c header-files jsmn

我正在查看一个仅 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 会扩展为以下内容之一,具体取决于定义的宏:

  1. 没有宏 - 函数定义(公共(public)函数是非静态的,私有(private)函数是)。
  2. JSMN_HEADER — 函数声明(仅适用于公共(public)函数)。
  3. 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/

相关文章:

c - for 循环和 size_t 的奇怪行为

c++ - 多个类在多个头文件中互相引用

c++ - 为什么 Qt 既不能识别我的头文件,也不能识别我的库文件?

c++ - 导致问题的头文件

c - 尝试读取 json 文件时出现段错误

c - 新手对C字符串的查询Jsmn jason解析器

c - 我应该在我的代码中使用 register 关键字吗?

c - 用c语言表示一个长数

json - 如何在嵌入式系统上用 jsmn 解析一个小的 JSON 文件?

c - 为什么需要为 GCC 中的代码覆盖传递两个编译器标志