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

  1. 因为这是非常大的概念上的改变。
  2. 没有真正的需要,因为与h / cpp的来源分开工作
  3. 因为C ++没有定义如何构build实际的“模块”库。 它留给编译器开发人员和链接器。
  4. “模块”有时非常依赖于平台,例如与共享对象完全不同的DLL。 所以在这些概念之间合并并不是那么简单。