C++20 modules 主要解决头文件导致的语义耦合、重复解析、宏污染和构建不确定性问题,编译加速仅为依赖实现和项目结构的副作用;其核心价值在于接口契约可验证、依赖可审计、宏作用域可收敛。
C++20 的 modules 并不能“从根本上加速编译速度”——它解决的是头文件机制带来的**语义耦合、重复解析、宏污染和构建不确定性**问题;编译速度提升是副作用,且高度依赖实现和项目结构。
每次 #include ,编译器都得:重新打开文件、预处理(展开所有宏)、重解析整个头文件语法树、检查模板定义是否变化。即使同一头文件被包含 100 次,就做 100 次完整解析。
DEBUG 在 A.h 定义,意外影响 B.cpp)#include 必须在某些头之前)std::vector,不导出内部辅助类”这种接口粒度关键不是语法,而是**切断隐式依赖链**。一个 export module math; 文件里,必须显式 export import std; 或 export template ,否则不会被导入者看到。
export 的声明/定义(如 namespace detail { ... })不会进入模块 ABI,也不会被导入者解析import 不是文本包含,不触发预处理,不传播宏,不读取注释或未导出的 static_assertimport 的支持仍有限;目前更可靠的是用 import std;(MSVC)或自定义模块封装 STLexport module myvec; export importexport import export namespace my { template class vector { std::unique_ptr data_; size_t size_ = 0; public: vector(std::initializer_list il); // ... }; }
常见原因不是模块本身无效,而是构建流程没对齐:
set_property(GLOBAL PROPERTY USE_FOLDERS ON) 或没正确设置 target_compile_features(... PRIVATE cxx_modules)
#include 和 import:只要有一个 #include "legacy.h",整个 TU 就退回传统模式(尤其 GCC 13 尚不支持混合)module myvec:detail;)没拆分好,导致修改内
部实现仍触发大量重编译-fmodules-cache-path,MSVC 的 /dM 和 PCH 共存问题)不是语言问题,是生态断层:
make clean 后首次构建可能漏掉 .pcm 编译import 的符号定义,因为没有统一的模块索引协议模块的价值不在“今天编译快 20%”,而在于让接口契约可验证、依赖可审计、宏作用域可收敛——这些好处要配合构建系统升级和团队规范才能释放。现在强行全量迁移,大概率换来一堆 module not found 和 CI 构建失败。