C ++模块 – 为什么他们从C ++ 0x中删除? 他们会回来吗?
我刚刚在C ++ 0x中发现了这个旧的C ++ 0x草案 。
这个想法是通过编写只有.cpp文件才能离开当前的.h / .cpp系统,然后在编译过程中生成模块文件,然后再由其他.cpp文件使用。
这看起来像一个非常棒的function。
但我的问题是:为什么他们从C ++ 0x中删除它? 是因为技术上的困难太多了吗? 时间不够? 你觉得他们会考虑为它做一个更加版本的C ++吗?
从C ++ Evolution的状态(Post San Francisco 2008) ,模块提案被分类为“单独的TR的标题:”
在发布之前,这些主题被认为太重要了,无法等待C ++ 0x之后的另一个标准,但是对于下一个标准来说,这些主题太过实验性,无法及时完成。 因此,这些function将尽早通过技术报告提供。
模块提案只是没有准备好,等待它会延迟完成C ++ 0x标准。 它并没有真正被删除,它从来没有被纳入工作文件。
C ++模块草案(C ++ 17之后的技术规范)
WG21在open-std.org上发布了一个草案和几个更新的C / C ++模块规范的修订版本。 我将只链接到这里的最新文件:
- 工作草案,模块N4610的 C ++扩展(2016年10月)。
- 第四版修订版为P0142R0 (2016年3月)。
- 模块的文字为P0143R2 (2016年3月)。
- 铿锵团队发表了他们的第二次修改版本: P0273R1 (2016年10月)。
以下博客文章包含标准会议的摘要,尤其是模块草案当前状态的摘要:
- 旅行报告: Lenexa的C ++标准会议 (2015年5月)。
- 旅行报告: 科纳C ++标准会议 (2015年10月)。
- 旅行报告: jackson维尔C ++标准会议 (2016年2月)
- 旅行报告: 奥卢的C ++标准会议 (2016年6月)
- 旅行报告: Issaquah的C ++标准会议 (2016年11月)。
更新:正如我在上面提到的科纳旅行报告中所解释的那样,目前有两个相互竞争的提议,一个来自Microsoft,一个来自Clang。 Microsoftbuild议的解决scheme不允许导出macros,而Clang团队的解决scheme将支持导出macros。 到目前为止,只有微软正式提交了一个模块规范的草案。
微软提出的模块规范
以下是对此提案包含的最重要概念的简要概述。 作为一个草案,这可能还是会改变的。 新的模块标准将包括以下内容:
一个module
关键字来声明一个模块,多个文件可以声明这个来构build一个模块(但是对于每个模块,只有一个编译单元可以包含一个export {}
部分):
module M;
import
关键字导入模块,而不是import
它也可能决定使用using module
,所以可以避免一个新的导入关键字。
import std.io; import module.submodule;
定义作为该模块一部分的公共声明的export
语法,将在导出块外部定义不应导出为模块一部分的非接口声明 。 声明可以是C / C ++中的任何types的声明,不仅是函数,还包括variables,结构体,模板,命名空间和类:
export { int f(int); double g(double, int); int foo; namespace Calc { int add(int a, int b); } } void not_exported_function(char* foo);
模块的一个重要变化是macros和预处理器定义将在模块本地,不会被导出。 因此,macros对导入的模块没有任何影响:
#define FILE "my/file" import std.io; //will not be impacted by the above definition
其重要的注意事项是,当前的预处理器系统和模块将能够共存,并且头文件仍然可以用于包括macros。
有关更详细的信息,我build议阅读草案。
铿锵模块
Clang一直在研究一个模块实现,可以在clang模块页面find 。 然而,clang目前没有为模块实现具体的语法,也就是说,Clang没有实现上述语法。 为了解释这个页面,包含以下语句:
目前,导入声明没有C或C ++语法。 Clang将跟踪C ++委员会中的模块提案。 请参阅包含作为导入部分以查看模块今天如何导入。
Clang当前实现的主要部分是“模块映射语言”,它允许为仍然使用头文件的现有代码编写模块映射。
模块macros输出
如上所述,macros观出口是否是最终模块TS的一部分仍然不清楚。 在P0273R1中 ,为macros的导出提出了以下语法:
#export define MAX(A,B) ((A) > (B)) ? (A) : (B);
Clang是第一个编译器,即使在标准化完成之前,也可以开始使用模块。 目前还没有太多的文档,但是可以在这里find示例代码:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/
Douglas Gregor(开发人员)的一些评论:
http://clang-developers.42468.n3.nabble.com/C-modules-td3619936.html
从理论上讲,你可以定义一些辅助macros,如begin_module,end_module,import_module,以防止将来可能出现的语法变化。
编辑1:
道格拉斯·格雷戈尔(Douglas Gregor)发表了一个关于他的实现
devmtg/2012-11/Gregor-Modules.pdf
编辑2:
clang中的模块支持已经在这里logging:
http://clang.llvm.org/docs/Modules.html
编辑3:
现在,Microsoft的C ++编译器也支持模块: http : //blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1.aspx
- 因为这是非常大的概念上的改变。
- 没有真正的需要,因为与h / cpp的来源分开工作
- 因为C ++没有定义如何构build实际的“模块”库。 它留给编译器开发人员和链接器。
- “模块”有时非常依赖于平台,例如与共享对象完全不同的DLL。 所以在这些概念之间合并并不是那么简单。