C++模块和C++ ABI

HC4*_*ica 25 c++ standards module abi

我一直在阅读有关C++模块提案(最新草案)的内容,但我并不完全了解它旨在解决的问题.

它的目的是允许由一个编译器构建的模块被任何其他编译器使用(当然,在相同的OS /架构上)?也就是说,提案是否相当于标准化C++ ABI?

如果没有,是否有另一个提议被认为是标准化C++ ABI并允许编译器互操作?

Nic*_*las 33

预编译头文件(PCH)是某些编译器可以为.cpp文件生成的特殊文件.他们究竟是这样的:预编译的源代码.它们是通过编译器提供的源代码,并构建为依赖于编译器的格式.

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

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

查看任何STL派生的标准库头文件.以<map>为例.很有可能这个文件要么是巨大的,要么有很多其他文件的#inclusions使得生成的文件巨大.这是必须要发生的很多C++解析.它必须发生在其中的每个 .cpp文件#include <map>中.每次编译源文件时,编译器都必须重新编译相同的东西.过度.结束了.一遍又一遍.

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

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

模块基本上与交叉编译器ABI无关(虽然其中一个很好,模块会使定义一个更容易).它们的根本目的是加快编译时间.


Xeo*_*Xeo 12

模块是Java,C#和许多其他现代语言提供的.它们极大地减少了编译时间,因为每次包含它时,不必一遍又一遍地解析今天标题中的代码.当你说#include <vector>,内容<vector>将被复制到当前文件中.#include真的只是复制和粘贴.

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

因为模块文件是由编译器生成的,所以它们与编译器的C++代码(AST)的内部表示紧密相关,因此很可能不是可移植的(就像今天的.o/ .so/ .a文件一样,因为名称修改等). ).


Eth*_*ris 8

C++中的模块必须比现在的解决方案更好,也就是说,当一个库由*.so文件和带有API的*.h文件组成时.他们必须用#includes解决今天的问题,即:

  • 需要macroguards(防止多次提供定义的宏)
  • 是严格基于文本的(所以它们可以被欺骗,在正常条件下它们被重新解释,这也有机会在不同的编译单元中以不同的方式看待下一个链接在一起)
  • 不要区分仅在工具上使用和从中派生的依赖库(特别是如果头部提供内联函数模板)

尽管Xeo说过,但Java或C#中不存在模块.事实上,在这些语言中,"加载模块"依赖于"好的,在这里你有CLASSPATH并通过它搜索以找到可能提供源文件实际使用的符号的任何模块".Java中的"import"声明根本不是"模块请求" - 与C++中的"using"相同(Java中的"import ns.ns2.*"与C++中的"using namespace ns :: ns2"相同) .我不认为这样的解决方案可以在C++中使用.我能想象的最接近的近似值是Vala中的包或Tcl中的模块(来自8.5版本的模块).

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