首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++模块和C++ ABI

C++模块和C++ ABI
EN

Stack Overflow用户
提问于 2012-01-31 08:07:23
回答 3查看 5.6K关注 0票数 25

我一直在阅读C++模块提案(latest draft),但我不完全理解它旨在解决什么问题。

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

如果没有,是否有其他提案正在考虑中,以标准化C++ ABI并允许编译器互操作?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-31 08:44:27

预编译头文件是某些编译器可以为.cpp文件生成的特殊文件。它们就是:预编译的源代码。它们是通过编译器输入的源代码,并内置于依赖于编译器的格式中。

PCH通常用于加速编译。您将常用的标头放入PCH中,然后只包含PCH。当您在PCH上执行包含时,您的编译器实际上不会执行通常的# #include工作。相反,它将这些预编译的符号直接加载到编译器中。不运行C++预处理器。不运行C++编译器。没有#包括一百万个不同的文件。一个文件被加载,符号直接显示在编译器的工作区中。

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

看看任何从STL派生的标准库头。以<map>为例。这个文件很有可能是巨大的,或者包含大量其他文件的#inclusions,这使得结果文件变得巨大。这需要进行大量的C++解析。对于其中包含#include <map>的每个.cpp文件,都必须发生这种情况。每次编译源文件时,编译器都必须重新编译相同的内容。完毕。再来一遍。一遍又一遍。

<map>会在不同的编译之间发生变化吗?没有,但是你的编译器不能知道这一点。所以它必须不断地重新编译它。每次接触.cpp文件时,它都必须编译此.cpp文件包含的每个头文件。即使您没有接触那些头文件或影响这些头文件的源文件。

PCH文件是解决此问题的一种方法。但它们是有限的,因为它们只是一个黑客。每个.cpp文件只能包含一个,因为它必须是.cpp文件包含的第一个内容。由于只有一个PCH,如果您更改了PCH (如向其添加新的标头),则必须重新编译该PCH中的所有内容。

模块本质上与交叉编译器ABI没有任何关系(尽管拥有一个这样的模块会更好,而且模块会让定义一个模块变得更容易)。它们的基本目的是加速编译时间。

票数 33
EN

Stack Overflow用户

发布于 2012-01-31 08:20:08

模块是Java、C#和许多其他现代语言所提供的。它们极大地减少了编译时间,因为今天的头中的代码不需要一遍又一遍地解析,每次都要包含它。当您说#include <vector>时,<vector>的内容将被复制到当前文件中。#include实际上就是复制和粘贴。

在模块世界中,您只需简单地输入import std.vector;,编译器就会加载该模块的查询/符号表。模块文件的格式使编译器可以轻松地解析和使用它。当模块被编译时,它也只被解析一次。在此之后,只需在编译器生成的模块文件中查询所需的信息。

因为模块文件是由编译器生成的,所以它们将与编译器的C++代码的内部表示紧密地联系在一起,因此很可能是不可移植的(就像今天的.o/.so/.a文件一样,因为名称混乱等原因)。

票数 12
EN

Stack Overflow用户

发布于 2012-07-21 04:28:28

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

  • 需要宏保护(防止多次提供定义的宏)
  • 是严格基于文本的(因此它们可以被欺骗,并且在正常情况下它们会被重新解释,这也使它们有机会在不同的编译单元中看起来不同,以便下一步链接在一起)
  • 不区分仅通过工具使用的依赖库和从其派生的依赖库(特别是如果标头提供内联函数模板)

不管Xeo怎么说,模块在Java或C#中是不存在的。事实上,在这些语言中,“加载模块”依赖于"ok,在这里你有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一样。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9072645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档