112

我刚刚发现了这个关于 C++0x 中模块的旧 C++0x 草案。

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

这看起来是一个非常棒的功能。

但我的问题是:他们为什么将它从 C++0x 中删除?是不是因为技术难度太大?时间不够?你认为他们会考虑为 C++ 的别有用心版本而工作吗?

4

4 回答 4

91

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

WG21 已在open-std.org上发布了 C/C++ 模块规范的草案和几个更新修订版。我将仅链接到此处的最新文档:

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

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

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

微软提出的模块规范

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

一个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 一直致力于模块实现,可以在clang 模块页面找到。然而,clang 目前并没有为模块实现具体的语法,也就是说,上面提到的语法都没有被 Clang 实现。为了解释这一点,该页面包含以下声明:

目前,导入声明没有 C 或 C++ 语法。Clang 将跟踪 C++ 委员会中的模块提案。请参阅作为导入的包含部分以了解今天如何导入模块。

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

从模块导出宏

如上所述,宏导出是否会成为最终Modules TS的一部分仍不清楚。在P0273R1中,针对宏的导出提出了以下语法:

#export define MAX(A,B) ((A) > (B)) ? (A) : (B);
于 2014-09-02T10:47:18.900 回答
71

根据C++ 演化状态(2008 年旧金山之后),模块提案被归类为“走向单独的 TR:”

这些主题被认为太重要了,不能等待 C++0x 之后的另一个标准才发布,但太实验性了,无法及时完成下一个标准。因此,这些功能将尽早通过技术报告提供。

模块提案还没有准备好,等待它会延迟完成 C++0x 标准。它并没有真正被删除,只是从未被纳入工作文件。

于 2010-08-29T19:07:38.483 回答
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

于 2012-03-03T16:28:18.220 回答
-42
  1. 因为这是非常大的概念变化。
  2. 没有真正需要它,因为将源分离到 h/cpp 可以完成这项工作
  3. 因为 C++ 没有定义实际的“模块”库是如何构建的。它将它留给编译器开发人员和链接器。
  4. “模块”有时完全依赖于平台,例如与共享对象完全不同的 DLL。因此,将这些概念融合起来并不是那么简单。
于 2010-08-29T19:10:50.193 回答