Please see our Visual Studio 2019 version 16.8 Preview 3 release notes for more of our latest features.
It has been some time since our last update regarding C++ Modules conformance. The toolset, project system, and IDE teams have been hard at work to create a first class C++ Modules experience in Visual Studio 2019. There is a lot to share, so let’s get right into it:
[/std:c++latest](https://devblogs.microsoft.com/cppblog/standard-c20-modules-support-with-msvc-in-visual-studio-2019-version-16-8/#std-latest)
Implies C++ Modules./std:c++latest
Implies C++ ModulesSince MSVC began down the path of implementing the Modules TS the toolset has always required the use of /experimental:module
on any compilation. Since the merge of Modules into the C++20 standard (we can officially say C++20 now!) the compiler has been working towards C++20 Modules conformance until precisely such a time that we can confidently roll Modules into /std:c++latest
. That time is now!
There are a few caveats to implying C++ Modules under /std:c++latest
:
/std:c++latest
now implies /permissive-
. This means that customers currently relying on the permissive behavior of the compiler in combination with /std:c++latest
are required to now apply /permissive
on the command line. Note: enabling /permissive
also disables the use of Modules.module
and import
being converted into keywords. We have documented some of the common scenarios. The paper MSVC implements in order to convert module
and import
into keywords has even more scenarios: P1857R1.std.*
Modules which ship with Visual Studio will not be available through /std:c++latest
alone. The standard library Modules have not yet been standardized and as such remain experimental. To continue using the standard library Modules users will need /experimental:module
as part of their command line options.C++20 added a new section to a primary Module interface known as the private Module fragment, [module.private.frag]. Private Module fragments allow authors to truly hide details of a library without having to create a separate C++ source file to contain implementation details. Imagine a scenario where a PIMPL pattern is used in a primary Module interface:
module;
#include <memory>
export module m;
struct Impl;
export
class S {
public:
S();
~S();
void do_stuff();
Impl* get() const { return impl.get(); }
private:
std::unique_ptr<Impl> impl;
};
module :private; // Everything beyond this point is not available to importers of 'm'.
struct Impl {
void do_stuff() { }
};
S::S():
impl{ std::make_unique<Impl>() }
{
}
S::~S() { }
void S::do_stuff() {
impl->do_stuff();
}
And on the import side:
import m;
int main() {
S s;
s.do_stuff(); // OK.
s.get(); // OK: pointer to incomplete type.
auto impl = *s.get(); // ill-formed: use of undefined type 'Impl'.
}
The private Module partition is an abstraction barrier shielding the consumer of the containing Module from anything defined in the purview of the private partition, effectively enabling single-“header” libraries with better hygiene, improved encapsulation, and reduced build system administrivia.
#announcement #c++ #buildsystem #c++ language #c++20 #intellisense #modules