C++;模块和C++;阿比 我一直在阅读C++模块建议(),但我不完全理解它的目的是什么。

C++;模块和C++;阿比 我一直在阅读C++模块建议(),但我不完全理解它的目的是什么。,c++,module,standards,abi,C++,Module,Standards,Abi,它的目的是允许一个编译器构建的模块被任何其他编译器使用(当然是在相同的OS/体系结构上)?也就是说,该提案是否对C++的ABI?标准化? 如果没有,有没有考虑到将标准化C++ ABI并允许编译器互操作?模块是java、C语言以及许多其他现代语言提供的。它们极大地减少了编译时间,这仅仅是因为今天的头文件中的代码不必在每次包含时反复解析。当您说#include时,的内容将被复制到当前文件中#include实际上就是复制和粘贴 在模块世界中,您只需说import std.vector和编译器加载该模块

它的目的是允许一个编译器构建的模块被任何其他编译器使用(当然是在相同的OS/体系结构上)?也就是说,该提案是否对C++的ABI?

标准化?

如果没有,有没有考虑到将标准化C++ ABI并允许编译器互操作?

模块是java、C语言以及许多其他现代语言提供的。它们极大地减少了编译时间,这仅仅是因为今天的头文件中的代码不必在每次包含时反复解析。当您说

#include
时,
的内容将被复制到当前文件中
#include
实际上就是复制和粘贴

在模块世界中,您只需说
import std.vector和编译器加载该模块的查询/符号表。模块文件的格式使编译器能够轻松地解析和使用它。在编译模块时,它也只被解析一次。之后,只需查询编译器生成的模块文件以获取所需的信息

因为模块文件是编译器生成的,它们将与编译器的C++代码的内部表示(AST)非常紧密地联系在一起,并且很可能不可移植(就像今天的代码< O.< /代码> /<代码>。所以/<代码> .< /Cord>文件,因为名称的颠倒等)。

< P>预编译头(PCH)是某些编译器可以为.cpp文件生成的特殊文件。它们就是:预编译的源代码。它们是通过编译器输入的源代码,并构建为依赖于编译器的格式

PCH通常用于加快编译速度。您将常用的标题放在PCH中,然后只包含PCH。在PCH上执行
#include
时,编译器实际上不会执行通常的#include工作。而是将这些预编译的符号直接加载到编译器中。不运行C++预处理器。不运行C++编译器。不,包括一百万个不同的文件。加载一个文件后,符号将直接在编译器的工作区中完全成形

我之所以提到这一切,是因为模块是完美形式的PCH。PCH基本上是一个建立在不允许实际模块的系统之上的巨大黑客。模块的目的最终是能够获取一个文件,生成包含符号的特定于编译器的模块文件,然后其他一些文件根据需要加载该模块。这些符号是预编译的,所以同样,也不需要包含一堆东西,运行编译器等等。您的代码显示,
import thing.foo
,它就出现了

查看任何STL派生的标准库标题。以
为例。很有可能这个文件是巨大的,或者包含了许多其他文件,使得生成的文件是巨大的。这是很多必须要分析的C++解析。对于每个包含
#include
的.cpp文件,都必须发生这种情况。每次编译源文件时,编译器都必须重新编译相同的内容。结束一遍又一遍。一次又一次

编译之间的
是否发生变化?没有,但是你的编译器不知道。所以它必须不断地重新编译它。每次触摸.cpp文件时,它都必须编译该.cpp文件包含的每个头。即使您没有接触那些标题或影响这些标题的源文件

PCH文件是解决这个问题的一种方法。但它们是有限的,因为它们只是一个黑客。每个.cpp文件只能包含一个,因为它必须是.cpp文件包含的第一项内容。因为只有一个PCH,如果你做了一些改变PCH的事情(比如添加一个新的头),你必须重新编译该PCH中的所有内容


模块基本上与交叉编译器ABI无关(尽管拥有其中一个会很好,模块会使定义一个更容易一些)。他们的根本目的是加快编译时间。

C++中的模块必须是比现在更好的解决方案,也就是说,当一个库由一个*.so文件和*.h文件加上API时。他们必须解决当今的问题,包括:

  • 需要宏保护(防止多次提供定义的宏)
  • 是严格基于文本的(因此它们可能会被欺骗,在正常情况下,它们会被重新解释,这也让我们有机会在不同的编译单元中以不同的方式进行下一步链接)
  • 不要区分仅以工具方式使用的依赖库和从中派生的依赖库(特别是在标头提供内联函数模板的情况下)
不管Xeo怎么说,模块在Java或C中并不存在。事实上,在这些语言中,“加载模块”依赖于“好的,这里有类路径并通过它进行搜索,以找到任何模块可能提供源文件实际使用的符号”。java中的“导入”声明根本不是“模块请求”——C++中的“使用”与“爪哇中的Nest.NS2.*”相同,“C++中使用NAMS:NS:NS2”。我认为这种解决方案不适用于C++。我能想象的最接近的近似值是Vala中的包或Tcl中的模块(8.5版本中的那些)

我想,C++模块是不可能跨平台的,也不可能是动态加载的(需要专用的C++动态模块加载器——这不是不可能的,但今天很难定义)。它们肯定会依赖于平台,并且在请求时也应该是可配置的。但是,一个稳定的C++ ABI实际上只需要在一个系统的范围内,就像现在的C++ ABI一样。