C++20 模块会改变静态库和共享库的结构吗?

Will C++20 modules change the anatomy of static and shared libraries?

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

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

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

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

因此,在我看来,模块并不能轻易替代通用 header/libraries。它们是轻量级(最佳header-only)和潜在的高度模板化代码的理想替代品,可多次包含在典型程序中。许多图书馆,最重要的是标准图书馆,都是这样的。但也有许多不同设计的库(小型API+重型二进制后端)。对于那些,我想,我们将不得不像以前一样继续使用 include/libraries。但是,C++ 是向后兼容的,所以混合模块和 include 完全没有问题。

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

因此,我相信在未来的某个时候会分发一些 C++ 模块,还有常规的 headers+ 库。模块本身可以分成许多文件(只有“导出的”符号对用户可见)。模块可能会遵循与 headers 截然不同的设计指南。 “每个模块一个class”很可能没有任何优势,而是“每个模块有一大堆逻辑连接的代码”。