Reputation: 5730
I am starting to experiment with Microsoft Visual Studio's C++ modules implementation. Microsoft splits the standard library into five modules:
I've replaced my standard library includes with the above modules, as appropriate for each file in my project. However, I include many third-party library files. Let's say for example, a third party library has an #include <memory>
in a header file, and I've already had import std.memory;
in my file before including the third party library's header file.
Does the std.memory
module define the include guards that would cause the third party library to skip the unnecessary #include <memory>
or is it including memory, even though the module covering <memory>
has already been included?
Does the standard have anything to say about this? This seems to be a significant issue during the transition to modules: if third-party libraries are used, the benefits to modules seems significantly reduced if their includes still occur as before.
Upvotes: 4
Views: 1539
Reputation: 474086
Exactly what a directive like #include <vector>
does is up to the implementation. The implementation could have a mechanism to detect both that vector
is being included by a module as well as that the definitions in vector
are already available due to a module import
. In such a scenario, the #include <vector>
directive could just do nothing or #include
a file that is empty.
And once the C++ standard library is modularized in the actual standard, and as modules implementations mature, these things could just be part of the implementation. However, such optimizations would be based on intrinsics specific to the compiler or explicit logic owned by the compiler. It would not necessarily be available for 3rd parties, so the overall issue remains.
The principle way to combat the issue is to not #include
3rd party API headers in modules; you import
such headers. This is why header import
directives are part of the modules system. By import
ing the header, you encourage the implementation to make sure that this header only gets compiled once.
Now yes, if you have 10 headers that you use import
on each #include <vector>
, then <vector>
will be compiled 10 times for those module headers. But if you import
one of those headers from 10 different files in your project, that header should only be compiled once. And such import
ed module headers should only need to be recompiled if the contents of those headers changes, so subsequent builds of your projects shouldn't require reprocessing 3rd party APIs.
Upvotes: 0
Reputation: 40013
C++20 does not specify modules for the standard library at all. Instead, it specifies that (most of) the library headers can be imported: import<vector>;
and so on. It is therefore either the case that the standard library components are attached to the global module, in which case a hypothetical C++23 std.vector
module interface unit might be as simple as
module;
#include<vector>
export module std.vector;
namespace std {
export using std::vector;
}
or even
export module std.vector;
export import<vector>;
or that they are attached to a named module, in which case the header <vector>
might be nothing but
import std.vector;
(plus feature-test macros).
In neither case does anything break if a translation unit does both
import std.vector;
#include<vector>
as might happen were it to #include
header files containing each of those lines: the two definitions of std::vector
are in different translation units, just like two C++98 translation units that #include<vector>
. There is still the question of efficiency: with the former strategy, it would be possible for a translation unit to import
and #include
the same components, and the named module can’t provide a macro to prevent reparsing it. An implementation using such a strategy might, however, choose to translate the #include
into an import<vector>;
to avoid that.
Note that, as with MSVC’s implementation, it may be the case that C++23 standard library modules are coarser than the headers, so that the above applies to (say) std.containers
and <vector>
, <deque>
, <map>
, etc. collectively.
Upvotes: 2