{"id":25409,"date":"2020-01-22T23:12:09","date_gmt":"2020-01-22T23:12:09","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=25409"},"modified":"2020-09-11T22:11:18","modified_gmt":"2020-09-11T22:11:18","slug":"c-modules-conformance-improvements-with-msvc-in-visual-studio-2019-16-5","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/c-modules-conformance-improvements-with-msvc-in-visual-studio-2019-16-5\/","title":{"rendered":"C++ Modules conformance improvements with MSVC in Visual Studio 2019 16.5"},"content":{"rendered":"<p>C++20 is right around the corner. Along with the new standard comes the much anticipated Modules feature! The compiler team <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/cpp-modules-in-visual-studio-2017\/\">initially announced<\/a> that we were working on the Modules TS back in 2017 and since then we have been hard at work improving the feature and improving compiler conformance around this feature. We finally feel it is time to share some of the progress we have made on the conformance front for Modules.<\/p>\n<h2>What&#8217;s new?<\/h2>\n<ul>\n<li><a href=\"#header-units\">Header units<\/a> are a new form of translation unit which act like portable PCHs.<\/li>\n<li><a href=\"#context-sensitive-keywords\">Context sensitive <code>module<\/code> and <code>import<\/code> keywords<\/a> provide users with more flexibility when using these terms as identifiers in code.<\/li>\n<li><a href=\"#global-module\">Global module fragment<\/a> is a way of separating non-modular code from module interface code when composing a module interface.<\/li>\n<li><a href=\"#module-partitions\">Module partitions<\/a> are a type of module interface which compose a larger module interface.<\/li>\n<li><a href=\"#intellisense\">IntelliSense<\/a> status as of Visual Studio 2019 version 16.6 Preview 2.<\/li>\n<\/ul>\n<h4><span id=\"header-units\">Header Unit Support<\/span><\/h4>\n<p>In C++20 <a href=\"http:\/\/eel.is\/c%2B%2Bdraft\/module.import#5\">[module.import]\/5<\/a> describes the import of a new translation unit type, the header unit. The semantics of this type of import are further elaborated on in [module.import]\/5 and one of the more important pieces of information is that macros defined in that imported header are also imported:\n<code>myheader.h<\/code><\/p>\n<pre class=\"\">#pragma once\r\n\r\n#include &lt;cstdio&gt;\r\n\r\n#define THE_ANSWER 42\r\n#define STRINGIFY(a) #a\r\n#define GLUE(a, b) a ## b<\/pre>\n<p><code>main.cpp<\/code><\/p>\n<pre class=\"\">import \"myheader.h\";\r\n\r\nint f() { return THE_ANSWER; }\r\n\r\nint main() {\r\n  const char* GLUE(hello_,world) = STRINGIFY(Hello world);\r\n  std::printf(\"%s\\n\", hello_world);\r\n}<\/pre>\n<p>The sample above can be compiled using the new <code>\/module:exportHeader<\/code> switch:\n<code>$ cl \/std:c++latest \/W4 \/experimental:module \/module:exportHeader myheader.h \/Fomyheader.h.obj\n$ cl \/std:c++latest \/W4 \/experimental:module \/module:reference myheader.h:myheader.h.ifc main.cpp myheader.h.obj<\/code><\/p>\n<p>Notice the use of <code>\/module:exportHeader<\/code>, the argument to this option is a path (relative or absolute) to some header file. The output of <code>\/module:exportHeader<\/code> is of our .ifc format. Meanwhile, on the import side, the option <code>\/module:reference<\/code> has a new argument form which is <code>&lt;path-to-header&gt;:&lt;path-to-ifc&gt;<\/code> and either one or both of the paths expressed in the argument to <code>\/module:reference<\/code> can be relative or absolute. It is also important to point out that without the <code>\/Fo<\/code> switch the compiler will <b>not<\/b> generate an object file automatically, the compiler will only generate the .ifc.<\/p>\n<p>One other intended use case of the <code>\/module:exportHeader<\/code> is for users (or build systems) to provide a text argument to it which represents some header name as the compiler would see. A quick example is:\n<code>$ cl \/std:c++latest \/EHsc \/experimental:module \/module:exportHeader \"&lt;vector&gt;\" \/module:showResolvedHeader\n&lt;vector&gt;\nNote: resolved &lt;vector&gt; to 'C:\\&lt;path-to-vector&gt;\\inc\\vector'<\/code><\/p>\n<p>This use of <code>\/module:exportHeader<\/code> enables the compiler to build header units using the header search mechanism as if the argument were written in source. This functionality also comes with a helper switch, <code>\/module:showResolvedHeader<\/code>, to emit the absolute path to the header file found through lookup.<\/p>\n<p><em>Note to readers: there is a known limitation with <code>\/module:exportHeader<\/code> and its interaction with <code>\/experimental:preprocessor<\/code> these two switches are currently incompatible and will be resolved in a future release.<\/em><\/p>\n<h4><span id=\"context-sensitive-keywords\">Context Sensitive <code>module<\/code> and <code>import<\/code> keywords<\/span><\/h4>\n<p>In the Modules TS both <code>module<\/code> and <code>import<\/code> were treated as keywords. It has since been realized that both of these terms are commonly used as identifiers for user code and hence a number of proposals were accepted into C++20 which add more restrictions as to when <code>module<\/code> and <code>import<\/code> are keywords. One such proposal was <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2019\/p1703r1.html\">P1703R1<\/a> which adds context sensitivity to the <code>import<\/code> identifier. Another such proposal\u2014but one which is not yet accepted\u2014is <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2019\/p1857r1.html\">P1857R1<\/a>. P1857R1 is interesting in that it is the most restrictive paper in defining when <code>module<\/code> and <code>import<\/code> are keywords or identifiers.<\/p>\n<p>As of 16.5 MSVC will implement both P1703R1 and P1857R1. The result of implementing the rules outlined in these two papers is that code such as:<\/p>\n<pre class=\"\">#define MODULE module\r\n#define IMPORT import\r\n\r\nexport MODULE m;\r\nIMPORT :partition;\r\nIMPORT &lt;vector&gt;;<\/pre>\n<p>Is no longer valid and the compiler will treat the macro expansion of both <code>MODULE<\/code> and <code>IMPORT<\/code> as identifiers, not keywords. For more cases like this please see the papers, in particular P1857R1 provides some useful comparison tables describing the scenarios affected by the change.<\/p>\n<h4><span id=\"global-module\">Global Module Fragment<\/span><\/h4>\n<p>Since the merging of Modules into C++20 there was another new concept introduced known as the global module fragment. The global module fragment is only used to compose module interfaces and the semantics of this area borrows semantics described in the Modules TS regarding entities attached to the global module. The purpose of the global module fragment is to serve as a space for users to put preprocessor directives like <code>#include<\/code>&#8216;s so that the module interface can compile, but the code in the global module fragment is not owned by or exported directly by the module interface. A quick example:<\/p>\n<pre class=\"\">module;\r\n#include &lt;string&gt;\r\n#include &lt;vector&gt;\r\nexport module m;\r\n\r\nexport\r\nstd::vector&lt;std::string&gt; f();<\/pre>\n<p>In this code sample the user wishes to use both <code>vector<\/code> and <code>string<\/code> but does not want to export them, they are simply an implementation detail of the function they wish to export, <code>f<\/code>. The global module fragment in particular is the region of code between the <code>module;<\/code> and <code>export module m;<\/code>. In this region the only code which can be written are preprocessor directives; <code>#if<\/code> and <code>#define<\/code> are fair game. It is important to note that if the first two tokens of the translation unit are <em>not<\/em> <code>module;<\/code> the interface unit is treated as though a global module fragment does not exist and this behavior is enforced through <a href=\"http:\/\/eel.is\/c++draft\/cpp.global.frag#1\">[cpp.global.frag]\/1<\/a>.<\/p>\n<h4><span id=\"module-partitions\">Module Partitions<\/span><\/h4>\n<p>Module partitions provide users with a new way of composing module interface units and organizing code of a module. At their very core, module partitions are pieces of a larger module interface unit and do not stand on their own as an interface to import outside of the module unit. Here is a quick example of a simple module interface which uses partitions:\n<code>m-part.ixx<\/code><\/p>\n<pre class=\"\">export module m:part;\r\n\r\nexport\r\nstruct S { };<\/pre>\n<p><code>m.ixx<\/code><\/p>\n<pre class=\"\">export module m;\r\nexport import :part;\r\n\r\nexport\r\nS f() { return { }; }<\/pre>\n<p><code>main.cpp<\/code><\/p>\n<pre class=\"\">import m; \/\/ 'm' is also composed of partition ':part'.\r\n\r\nint main() {\r\n  f();\r\n}<\/pre>\n<p>To compile the sample:\n<code>cl \/experimental:module \/std:c++latest \/c m-part.ixx\ncl \/experimental:module \/std:c++latest \/c m.ixx\ncl \/experimental:module \/std:c++latest main.cpp m.obj<\/code>\nNotice that we did not explicitly add <code>\/module:reference<\/code> to any invocation of the compiler, this is because we have introduced a naming scheme for module partitions which ease the use of the feature\u2014just like we have for normal module interface units where the filename represents the module name directly. The pattern that module partitions use is <code>&lt;primary-module-name&gt;-&lt;module-partition-name&gt;<\/code>. If your module partitions follow that pattern the compiler can automatically find interface units for partitions. Of course, should you actually want to specify the module interfaces on the command line simply add the appropriate <code>module:reference<\/code> arguments.<\/p>\n<p>The standard refers to partitions in general as being interface units <a href=\"http:\/\/eel.is\/c%2B%2Bdraft\/module#unit-3\">[module.unit]\/3<\/a>, however there is one exception and that is what we refer to as an &#8220;internal&#8221; partition. These internal partitions are not interfaces and only serve to facilitate the implementation details of a module unit. It is expressly ill-formed to export an internal partition (see translation unit 3 in section 4 of [module.unit]). MSVC implements the creation of internal partitions through a new switch <code>\/module:internalPartition<\/code>. An example of using an internal partition:<\/p>\n<p><code>m-internals.cpp<\/code> <em>note the .cpp extension<\/em><\/p>\n<pre class=\"\">module m:internals;\r\n\r\nvoid g() { } \/\/ No declaration can have 'export' in an internal partition.<\/pre>\n<p><code>m.ixx<\/code><\/p>\n<pre class=\"\">export module m;\r\nimport :internals; \/\/ Cannot export this partition.\r\n\r\nexport\r\nvoid f() { g(); }<\/pre>\n<p>To compile this interface:\n<code>cl \/experimental:module \/std:c++latest \/module:internalPartition \/c m-internals.cpp\ncl \/experimental:module \/std:c++latest \/c m.ixx<\/code>\nAs previously mentioned, the <code>:internals<\/code> partition can only be used to implement parts of the module interface <code>m<\/code> and cannot contribute to it directly.<\/p>\n<h4><span id=\"intellisense\">IntelliSense<\/span><\/h4>\n<p><b>(status as of Visual Studio 2019 version 16.6 Preview 2)<\/b>\nKeen readers might have noticed nascent understanding in IntelliSense for consuming modules. While still is far from full-fledged support for production and consumption of modules in the IDE \u2013 which we intend to provide as we move towards finalization of C++20 conformance, it shows initial capabilities which we are building on.\nAs soon as a translation unit consuming a module with an <code>import<\/code> is configured using Property Pages for <code>\/std:c++latest<\/code>, <code>\/experimental:module<\/code>, and any necessary module lookup path options, and the imported module is generated, the IntelliSense processing should pick the relevant .ifc file up.\nThe existing support will recognize namespaces, free functions, and their parameters from the imported module after they are typed in the program. The names however will not be offered in the Autocomplete\/Member List, and the processing will likely fail on other language constructs such as classes or templates.\nStay tuned as we expand the support in future releases!<\/p>\n<h2>Closing Thoughts<\/h2>\n<p>C++20 is bringing a lot of new concepts (literally and figuratively) to C++ and Modules are one of the largest contributors to how we will write code differently in the future. These MSVC conformance changes will help users facilitate the transition into thinking about how we organize and reason about interfaces to our APIs. As with all of our preview features the switches and compiler behavior with respect to modules are subject to change once we are ready to declare the toolset C++20 complete.<\/p>\n<p>We urge you to go out and try using MSVC with Modules. 16.5 is available right now in preview through the <a href=\"https:\/\/visualstudio.microsoft.com\/downloads\/\">Visual Studio 2019 downloads<\/a> page!<\/p>\n<p>As always, we welcome your feedback. Feel free to send any comments through e-mail at <a href=\"mailto:visualcpp@microsoft.com\">visualcpp@microsoft.com<\/a> or through <a href=\"https:\/\/twitter.com\/visualc\">Twitter @visualc<\/a>. Also, feel free to follow me on Twitter <a href=\"https:\/\/twitter.com\/starfreakclone\">@starfreakclone<\/a>.<\/p>\n<p>If you encounter other problems with MSVC in VS 2019 please let us know via the <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio?view=vs-2019\">Report a Problem<\/a> option, either from the installer or the Visual Studio IDE itself. For suggestions or bug reports, let us know through <a href=\"https:\/\/developercommunity.visualstudio.com\/\">DevComm.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++20 is right around the corner. Along with the new standard comes the much anticipated Modules feature! The compiler team initially announced that we were working on the Modules TS back in 2017 and since then we have been hard at work improving the feature and improving compiler conformance around this feature. We finally feel [&hellip;]<\/p>\n","protected":false},"author":39620,"featured_media":25457,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[270],"tags":[140,100,2064,246],"class_list":["post-25409","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcement","tag-c","tag-c-language","tag-c20","tag-modules"],"acf":[],"blog_post_summary":"<p>C++20 is right around the corner. Along with the new standard comes the much anticipated Modules feature! The compiler team initially announced that we were working on the Modules TS back in 2017 and since then we have been hard at work improving the feature and improving compiler conformance around this feature. We finally feel [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/25409","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/39620"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=25409"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/25409\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/25457"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=25409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=25409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=25409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}