C ++模块-为什么将它们从C ++ 0x中删除?他们会稍后回来吗?


110

我刚刚发现有关C ++ 0x中模块的旧C ++ 0x草案

这个想法是通过只编写.cpp文件来摆脱当前的.h / .cpp系统,然后在编译过程中生成模块文件,然后再由其他.cpp文件使用。

这看起来像一个很棒的功能。

但是我的问题是:为什么他们从C ++ 0x中删除了它?是因为技术难题太多吗?时间不够?而且您认为他们会考虑针对C ++的新版本进行开发吗?

Answers:


70

根据《C ++演进状态》(旧金山,2008年发布),“模块”提案被归类为“前往单独的TR:”

这些主题被认为太重要了,以至于在C ++ 0x之后等待发布另一个标准才发布,但是过于实验性,无法及时制定下一个标准。因此,这些功能将尽快由技术报告提供。

模块提议只是尚未准备好,等待它会延迟完成C ++ 0x标准。它并没有真正删除,只是从未合并到工作文件中。


89

C ++模块草案(C ++ 17之后的技术规范)

WG21在open-std.org上发布了C / C ++模块规范的草案和若干修订版。我将在这里仅链接到最新文档:

  • 工作草案,模块N4610的 C ++扩展(2016年10月)。
  • 第四版发布为P0142R0(2016年3月)。
  • 发布为P0143R2的模块用语(2016年3月)。
  • 铛团队发布了其更改的第二个修订版:P0273R1(2016年10月)。

以下博客文章包含标准会议的摘要,尤其是模块草案的当前状态的摘要:

更新:正如我在上面链接到的科纳之行报告中所解释的那样,当前有两个相互竞争的提案,一个来自微软,另一个来自Clang。Microsoft提出的解决方案不允许导出宏,而Clang团队的解决方案将支持导出宏。到目前为止,只有Microsoft正式提交了模块规范草案。

Microsoft提出的模块规格

这里是该提案包含的最重要概念的快速概述。作为草案,可能仍会更改。新模块标准将包括以下内容:

module关键字声明的模块,多个文件可以声明此建立一个模块(但每个模块仅一个编译单元可以包含一个export {}部分):

module M;

import代替模块import也可以决定使用导入模块的关键字using module,因此可以避免使用新的导入关键字。

import std.io;
import module.submodule;

export语法,它定义了公共的声明作为此模块的一部分,非接口声明不应被导出作为该模块的一部分将在出口块之外来定义。声明可以是C / C ++中的任何类型的声明,即不仅是函数,而且还可以是变量,结构,模板,名称空间和类:

export {
    int f(int);
    double g(double, int);

    int foo;

    namespace Calc {
         int add(int a, int b);
    }        
}

void not_exported_function(char* foo);

模块的一个重要变化是宏和预处理器定义对于模块而言是本地的,不会被导出。因此,宏对导入的模块没有任何影响:

#define FILE "my/file"
import std.io;   //will not be impacted by the above definition

重要的注意事项是,当前的预处理器系统和模块都将能够共存,并且标头仍可以用于例如包含宏。

有关更多详细信息,我建议阅读草案。

铛模块

Clang一直在致力于模块的实现,可以在clang modules页面上找到它。但是,clang当前没有为模块实现具体的语法,也就是说,Clang尚未实现上述语法。为了对此进行解释,该页面包含以下语句:

当前,没有用于导入声明的C或C ++语法。Clang将在C ++委员会中跟踪模块提议。请参阅“包括为导入”部分,以了解如何今天导入模块。

Clang当前实现的主要部分是“模块映射语言”,它允许为仍使用头文件的现有代码编写模块映射。

从模块宏导出

如上所述,目前尚不清楚宏输出是否将成为最终模块TS的一部分。在P0273R1中,为导出宏提出了以下语法:

#export define MAX(A,B) ((A) > (B)) ? (A) : (B);

2
从2018年拉珀斯维尔(Rapperswil)更新起,有加布里埃尔·多斯·瑞斯(Gabriel dos Reis)和理查德·史密斯(Richard Smith)的合并提案,p1103r0。botondballo.wordpress.com/2018/06/20/...
德韦恩·罗宾逊

32

Clang是第一个甚至在标准化完成之前就开始在模块上工作的编译器。没有太多的文档,但是可以在这里找到示例代码:http :
//llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/

Douglas Gregor(实现它们的开发人员)的一些评论:http :
//clang-developers.42468.n3.nabble.com/C-modules-td3619936.html

理论上,您可以定义一堆帮助程序宏,例如begin_module,end_module,import_module,以保护自己免受将来可能对语法的任何更改。

编辑1:
道格拉斯·格雷戈尔(Douglas Gregor)发布了有关其实现的演示文稿:http :
//llvm.org/devmtg/2012-11/Gregor-Modules.pdf?=submit

编辑2:
clang中的模块支持已在此处记录: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


-39
  1. 因为这是很大的概念变化。
  2. 由于将源与h / cpp分离就可以了,所以没有真正的需要
  3. 因为C ++没有定义实际的“模块”库的构建方式。它将它留给编译器开发人员和链接程序。
  4. 有时“模块”完全依赖于平台,例如与共享对象完全不同的DLL。因此,在这些概念之间合并并不是一件容易的事。

78
当然有必要。.h / .cpp是一个非常糟糕的过时解决方法。模块系统将是一个巨大的变化,但这是标准委员会显然认为重要的一个系统。
jalf

13
头构建模型是问题的模块是为了解决,而不是溶液。此外,模块不能替代DLL / SO。
bames53 2013年

5
这是错误的:1 .模块提议要格外小心,以确保与现有标头系统的向后兼容性,因此将来在引入模块时不会中断。2.充分证明了将头模块的编译时间复杂度从O(M * N)复杂度降低到O(M + N)的需要。3.模块标准将不会规定如何编译和链接模块,但会添加明确的语义以区分模块的私有API和公共API。4. DLL或共享对象的二进制格式不受该标准的影响。
lanoxx

3
“没有真正的需求,因为将源分离为h / cpp即可完成工作”,用链锯切割注入的手指也是如此,但这并不意味着这不是问题!只需查看.NET或任何其他更新的lang,就必须以某种方式对事物进行排序,以使其真正可见或正确构建,这是一个巨大的负担,需要消除。
2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.