【问题标题】:Header-only and static-inline-only library in CC 中的仅标头和仅静态内联库
【发布时间】:2015-01-20 02:48:47
【问题描述】:

我在 C 中编写了仅小型标头和 static-inline-only 库。将其应用于大型库时会是一个坏主意吗?还是仅使用标头版本的运行时间可能会更快?好吧,不考虑明显的编译时间差异。

【问题讨论】:

  • 函数一般不应该在标题中定义。
  • @2501 在标题中使用静态内联函数并不罕见。
  • 即使那是真的,它仍然是错误的。
  • @2501 这样做是为了保证函数定义在使用之前出现,以确保发生内联。我不会说 static inline 是“错误的”,因为那时没有外部链接。
  • @Dmitri 如果用户开始使用并比较仅是静态内联标头的库的函数指针会发生什么。

标签: c static inline-functions header-only


【解决方案1】:

是的,这是个坏主意——尤其是与更大的库集成时

内联函数的复杂性问题通常会随着这些库被包含在内而增加,并且对更多翻译和更复杂的标题包含图可见——这在大型项目中很常见。随着翻译数量和依赖关系的增加,构建变得更加耗时。这种增加通常不是线性复杂度。

这在 C++ 中运行是有原因的,但在 C 中却不行。inline 导出语义不同。简而言之,您最终将在 C 中生成大量函数副本(以及函数的变量)。 C++ 对它们进行重复数据删除。 C 没有。

此外,内联并不是提高速度的灵丹妙药。该方法通常会增加您的代码大小和可执行文件大小。大型函数可以创建较慢的代码。程序/功能的副本也会使您的程序变慢。较大的二进制文件需要更多时间来链接和初始化(=启动)。通常越小越好。

最好考虑替代方案,例如链接时间优化、整个程序优化、库设计,使用 C++ 并避免在标头中定义 C。

还要记住,编译器可以消除死代码,而链接器可以消除未使用的函数。

【讨论】:

  • 您是否有参考表明非静态内联 C 函数不会在链接阶段进行重复数据删除?或者更确切地说,它们的重复数据删除方式与 C++ 不同?如果是在什么平台上?
【解决方案2】:

我编写了一个单元测试框架* 作为单个 C89 头文件。基本上所有内容都是宏或标记为静态的,并且链接时间优化(部分)会删除结果。

这是一个易于使用的胜利,因为与构建系统的集成是微不足道的。

编译时间没问题,因为这是 C,但结果函数重复确实让我有点困扰。因此,它可以用作标题 + 源,而不是通过在单个源文件中的 #include 之前设置宏,例如

#define MY_LIB_HEADER_IMPLEMENTATION
#include "my_lib.h"

我认为我不会将这种方法用于更大的项目,但我认为它对于本质上是一组单元测试宏来说是最佳的。

  • 在“不要打电话给我们,我们会打电话给你”的意义上

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多