【问题标题】:Will C++20 modules change the anatomy of static and shared libraries?C++20 模块会改变静态库和共享库的结构吗?
【发布时间】:2021-01-14 05:10:25
【问题描述】:

传统上,C++ 库由头文件 + 在二进制文件中编译的实现组成(.a.so.dylib.dll,...)。源代码中的头文件为#included,二进制部分链接到最终的可执行文件。

C++20 中的模块会改变这种布局吗?如果是这样,操作系统是否必须升级它们分发其核心库的方式,例如Linux 中的标准库或 Windows 中的其他核心 dll?

【问题讨论】:

  • 好吧,我还没有研究过最新的草案规范,但始终需要做的一件事是向后兼容性。现有软件的堆积如山能够被编译,即使一种语言引入了“更好的方法”。 .h 文件策略原始的,但它永远不会消失。
  • IIUC 模块的设计使编译器能够在编译时生成一种“模块定义文件”。这对我来说似乎很让人联想到预编译的头文件。所以我认为这种二元性不会发生任何变化。只有编译器开关可能会改变。
  • 从 C++ 20 开始,规范中没有标准库模块,这是 C++23 target: Now that Modules are in C++20, C++23 should ship with a specification of how the functionality of the standard library is exposed as modules.
  • 模块几乎只是纯编译的头文件,所以几乎只是对现有头文件的直接交换,我认为其他任何事情都不会改变
  • 二进制文件应该仍然存在,但确实,提供头文件和/或模块定义文件可能会有所不同(并且由于模块定义格式尚未标准化,头文件似乎更便携)

标签: c++ c++20 c++-modules


【解决方案1】:

当然。与传统的标头/库相比,模块是向用户表示库代码的一种非常不同的类型。模块的主要优点是让编译器将其解析到 抽象语法树 (AST) 的级别。每个模块只发生一次 - 与每次包含特定头文件时相反。因此,加速的一种可能性是将非常频繁的头文件转换为模块并节省大量编译器时间,而不是多次重新编译为 AST,而只需一次。 AST 也适用于模板……它是对 C++ 语言的通用且完整的描述。

但这也是目前主要的“缺点”:AST 绝对依赖于编译器。供应商、系统甚至编译器版本之间没有稳定性。所以分发 AST 没有任何意义,至少在当前的工具链环境中是这样。

因此,据我了解,模块不容易替代常见的标头/库。它们是轻量级(最好的仅标头)和可能在典型程序中多次包含的高度模板化代码的理想替代品。许多库,主要是标准库,都是这样的。但也有许多不同设计的库(小型 API + 重型二进制后端)。对于那些,我想,我们将不得不像以前一样继续使用包含/库。但是,C++ 是向后兼容的,因此将模块与包含混合使用完全没有问题。

此外,模块可以只包装包含文件(例如,使用 API)。这可能不是一个非常强大的模块用法,但可能会导致更统一的编程模式。在这种情况下,您仍然需要将“so”或“dylib”或任何库链接到生成的代码。

因此,我相信未来某个时候会同时发布一些 C++ 模块,以及传统的头文件+库。模块本身可以拆分为许多文件(只有“导出”的符号对用户可见)。模块可能会遵循与标头非常不同的设计准则。 “每个模块一个类”很可能没有任何优势,而是“每个模块有一大堆逻辑连接的代码”。

【讨论】:

    猜你喜欢
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    相关资源
    最近更新 更多