{"id":26946,"date":"2020-10-29T15:00:54","date_gmt":"2020-10-29T15:00:54","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=26946"},"modified":"2022-08-11T20:54:55","modified_gmt":"2022-08-11T20:54:55","slug":"a-tour-of-cpp-modules-in-visual-studio","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/a-tour-of-cpp-modules-in-visual-studio\/","title":{"rendered":"A Tour of C++ Modules in Visual Studio"},"content":{"rendered":"<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Content outdated<\/strong><\/p> For up-to-date documentation see <a class=\"Hyperlink SCXW208931926 BCX8\" href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/cpp\/modules-cpp?view=msvc-170\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW208931926 BCX8\" lang=\"EN-GB\" xml:lang=\"EN-GB\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW208931926 BCX8\" data-ccp-charstyle=\"Hyperlink\">Overview of modules in C++<\/span><\/span><\/a>.<\/div>C++ module support has arrived in Visual Studio! Grab the latest <a href=\"https:\/\/visualstudio.com\/preview\">Visual Studio Preview<\/a> if you want to try it out. <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/cpp\/modules-cpp\">C++ modules<\/a> can help you compartmentalize your code, speed up build times, and they work seamlessly, side-by-side with your existing code.<\/p>\n<p>This preview only supports C++ modules in the IDE for MSBuild projects. While the MSVC toolset is supported by any build system, Visual Studio\u2019s IDE support for CMake doesn\u2019t support C++ modules yet. We will let you know once it is! As always, please try it out and let us know if you have any feedback.<\/p>\n<h2>Module Basics<\/h2>\n<p>C++ modules allow you to closely control what is made available to the translation units that consume them. Unlike headers, they won\u2019t leak macro definitions or private implementation details (no ridiculous prefixes needed). Also, unlike headers, they are built once and then can be consumed many times across your projects, reducing build overhead.<\/p>\n<p>C++20 introduces new keywords to define and consume modules and Visual Studio uses a new file type \u201c.ixx\u201d to define a module\u2019s interface. Read on for the details.<\/p>\n<h2>Getting Started with Modules in Visual Studio<\/h2>\n<p>If you created a brand-new project in the latest preview, you don\u2019t need to do anything. However, before you can add or consume modules in existing projects you need to make sure you are using the latest C++ Language Standard.<\/p>\n<p>To do this, set the C++ Language Standard to \u201cPreview \/std:c++latest\u201d. If you have multiple projects in your solution, remember to do this for all of them.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Cpp-Language-Standard-Latest.png\"><img decoding=\"async\" class=\"size-full wp-image-26949 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Cpp-Language-Standard-Latest.png\" alt=\"General &gt; C++ Language Standard, set to \u201cPreview \/std:c++latest\u201d\" width=\"1425\" height=\"820\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Cpp-Language-Standard-Latest.png 1425w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Cpp-Language-Standard-Latest-300x173.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Cpp-Language-Standard-Latest-1024x589.png 1024w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Cpp-Language-Standard-Latest-768x442.png 768w\" sizes=\"(max-width: 1425px) 100vw, 1425px\" \/><\/a><\/p>\n<p>And that\u2019s it! You are ready to use C++ modules with Visual Studio.<\/p>\n<h3>Creating Modules<\/h3>\n<p>To add a module to a project you will need to create a module interface. These are normal C++ source files with the extension \u201c.ixx\u201d. They can include headers, import other modules, and will include the exported definitions of your module. You can add as many of these to a project as you want.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Add-Module.png\"><img decoding=\"async\" class=\"size-full wp-image-26951 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Add-Module.png\" alt=\"Add New Item &gt; \u201cC++ Module Interface Unit (.ixx)\u201d\" width=\"1204\" height=\"766\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Add-Module.png 1204w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Add-Module-300x191.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Add-Module-1024x651.png 1024w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Add-Module-768x489.png 768w\" sizes=\"(max-width: 1204px) 100vw, 1204px\" \/><\/a><\/p>\n<p>Here\u2019s how this then looks in the Solution Explorer. In this example, the <code>fib<\/code> and <code>printer<\/code> projects both define C++ modules.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Solution-Explorer-Modules.png\"><img decoding=\"async\" class=\"aligncenter wp-image-26952 size-full\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Solution-Explorer-Modules.png\" alt=\"Solution Explorer with three module interfaces\" width=\"477\" height=\"741\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Solution-Explorer-Modules.png 477w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Solution-Explorer-Modules-193x300.png 193w\" sizes=\"(max-width: 477px) 100vw, 477px\" \/><\/a><\/p>\n<p><strong><em>Note:<\/em><\/strong> While this example shows all module interfaces in \u201c.ixx\u201d files, any C++ source file can be treated as a module interface. To do this, set the \u201cCompile As\u201d property on a source file to \u201cCompile As Module\u201d. The \u201cCompile As\u201d property can be found on the \u201cAdvanced\u201d tab on any source file&#8217;s properties page.<\/p>\n<h3>Exporting Modules<\/h3>\n<p>So, what actually goes into a module interface? The example below defines a simple module called <code>DefaultPrinter<\/code> and exports a single struct:<\/p>\n<pre class=\"prettyprint\">module; \/\/begins global module fragment\r\n\r\n#include &lt;iostream&gt;\r\n\r\nexport module DefaultPrinter;\r\n\r\nexport struct DefaultPrinter\r\n{\r\n    void print_element(int e)\r\n    {\r\n        std::cout &lt;&lt; e &lt;&lt; \" \";\r\n    }\r\n\r\n    void print_separator()\r\n    {\r\n        std::cout &lt;&lt; \", \";\r\n    }\r\n\r\n    void print_eol()\r\n    {\r\n        std::cout &lt;&lt; '\\n';\r\n    }\r\n};\r\n<\/pre>\n<p>To break the example down a bit, you can see the new export syntax on lines 1, 5, and 7. Line 1 specifies that this is a module interface. Line 5 defines and exports the module itself and line 7 exports a struct. Each module can export many items, such structs, classes, functions, and templates.<\/p>\n<p>Module interfaces can include headers and import other modules. When they are imported, they will not leak any details from these included headers or modules unless you explicitly import them. This isolation can help avoid naming collisions and leaking implementation details. You can safely define macros and use namespaces in module interfaces too. They will not leak like traditional headers.<\/p>\n<p>To\u00a0<code>#include<\/code> headers in a module interface, ensure you put them in the\u00a0<em>global module fragment<\/em> between\u00a0<code>module;<\/code> and\u00a0<code>export module mymodule;<\/code>.<\/p>\n<p>This example puts the implementation in the module\u2019s interface, but that is optional. If you look back at the solution explorer before you can see the fibgen.ixx interface has a corresponding implementation in fibgen.cpp.<\/p>\n<p>Its interface looks like this:<\/p>\n<pre class=\"prettyprint\">export module FibGenerator;\r\nexport fib gen_fib(int start, int &amp;len);\r\n<\/pre>\n<p>With a corresponding implementation:<\/p>\n<pre class=\"prettyprint\">module FibGenerator;\r\n\r\nfib gen_fib(int start, int &amp;len)\r\n{\r\n\t\/\/...\r\n}\r\n<\/pre>\n<p>Here, the interface defines the module name and exports <code>gen_fib<\/code>. The corresponding implementation uses the <code>module<\/code> keyword to define which module the implementation belongs to so everything can be combined into a cohesive unit automatically at build time.<\/p>\n<h3>Consuming Modules<\/h3>\n<p>To consume modules, use the new <code>import<\/code> keyword.<\/p>\n<pre class=\"prettyprint\">module;\r\n#include &lt;ranges&gt;\r\n#include &lt;concepts&gt;\r\n\r\nimport DefaultPrinter;\r\n\r\nstruct DefaultFormatter\r\n{\r\n    template&lt;is_series S, is_printer T&gt;\r\n    void format(T t, S s)\r\n    {\r\n        while (!s.done())\r\n        {\r\n            t.print_element(s.next());\r\n            t.print_separator();\r\n        }\r\n        t.print_eol();\r\n    }\r\n};<\/pre>\n<p>All exported items from the module interface will be available for use. This example makes use of the <code>DefaultPrinter<\/code> module in the first example, importing it on line 5.<\/p>\n<p>Your code can consume modules in the same project or any referenced ones automatically (using <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/managing-references-in-a-project\">project-to-project references<\/a> to static library projects).<\/p>\n<h4>Consuming Modules from Other Modules<\/h4>\n<p>You can also import modules from another module interface. Here is an example that expands on the <code>DefaultPrinter<\/code> module above:<\/p>\n<pre class=\"prettyprint\">module;\r\n#include &lt;iostream&gt;\r\nimport DefaultPrinter;\r\n\r\nexport module TabbedPrinter;\r\n\r\nexport struct TabbedPrinter : DefaultPrinter\r\n{\r\n    void print_separator()\r\n    {\r\n        std::cout &lt;&lt; \"\\t\";\r\n    }\r\n};<\/pre>\n<p>This example imports the <code>DefaultPrinter<\/code> module above and overrides its <code>print_separator<\/code> function. Other code can now import this <code>TabbedPrinter<\/code> without needing to worry about the details of <code>DefaultPrinter<\/code>. Visual Studio will make sure everything is built in the right order.<\/p>\n<h3>External Modules<\/h3>\n<p>It is also possible to reference modules that exist on disk, instead of ones belonging to another project in the solution. Care needs to be taken here, however, because modules are compiled, binary files. You must make sure they are compatible with the way you are building your projects.<\/p>\n<p>You can tell Visual Studio to look for modules on disk by editing the Additional Module Dependencies property:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Additional-Module-Dependencies.png\"><img decoding=\"async\" class=\"size-full wp-image-26957 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Additional-Module-Dependencies.png\" alt=\"C\/C++ &gt; General &gt; Additional Module Dependencies, you can add modules with \u201c\/reference[[module_name]=]path\u201d, multiple modules can be separated by semicolons\" width=\"1180\" height=\"820\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Additional-Module-Dependencies.png 1180w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Additional-Module-Dependencies-300x208.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Additional-Module-Dependencies-1024x712.png 1024w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Additional-Module-Dependencies-768x534.png 768w\" sizes=\"(max-width: 1180px) 100vw, 1180px\" \/><\/a><\/p>\n<h2>IntelliSense and Modules<\/h2>\n<p>All the IntelliSense features you know and love also work with modules. Features like code completion, parameter help, Find All References, Go To Definition and Declaration, rename, and more all work across solutions the way you would expect when you use modules.<\/p>\n<p>Here you can see Find All References and Peek Definition working with our <code>TabbedPrinter<\/code> module above. For instance, it can show all references of the <code>DefaultPrinter<\/code>\u00a0structure exported from the <code>DefaultPrinter<\/code>\u00a0module and display its definition:<\/p>\n<p><b>Find All References<\/b>\n<a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Find-All-References-X.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-26987\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Find-All-References-X.png\" alt=\"Find All References of the \u201cDefaultPrinter\u201d structure across the solution\" width=\"1088\" height=\"1065\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Find-All-References-X.png 1088w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Find-All-References-X-300x294.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Find-All-References-X-1024x1002.png 1024w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Find-All-References-X-768x752.png 768w\" sizes=\"(max-width: 1088px) 100vw, 1088px\" \/><\/a><\/p>\n<p><b>Peek Definition<\/b>\n<a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Peek-Definition.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-26979\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Peek-Definition.png\" alt=\"Peek Definition of the \u201cDefaultPrinter\u201d structure\" width=\"1176\" height=\"649\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Peek-Definition.png 1176w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Peek-Definition-300x166.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Peek-Definition-1024x565.png 1024w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Module-Peek-Definition-768x424.png 768w\" sizes=\"(max-width: 1176px) 100vw, 1176px\" \/><\/a><\/p>\n<p>You can also Go To or Peek the Definition of a module itself from anywhere that imports it:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Peek-Module-Import.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-26993\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Peek-Module-Import.png\" alt=\"Peek Definition of an imported module, &quot;DefaultPrinter&quot;\" width=\"1172\" height=\"643\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Peek-Module-Import.png 1172w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Peek-Module-Import-300x165.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Peek-Module-Import-1024x562.png 1024w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2020\/10\/Peek-Module-Import-768x421.png 768w\" sizes=\"(max-width: 1172px) 100vw, 1172px\" \/><\/a><\/p>\n<h2>See Modules in Action<\/h2>\n<p>To see all of this in action, check out our modules demo from <a href=\"https:\/\/cppcon.org\/\">CppCon 2020<\/a>. There are many other demos of the latest Visual Studio and C++20 features in action too if you are interested.<\/p>\n<p><iframe src=\"https:\/\/www.youtube.com\/embed\/Va9-Qe3WzJ8\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<h2>Header Units<\/h2>\n<p>A header unit is a standard C++ incantation to invoke the generation of metadata (IFC files) &#8211; for well-behaved header files, in particular standard library headers &#8211; similar to those generated for modules with the goal of speeding up overall build time, if done judiciously. However, unlike Modules, header units do not really provide isolation the way Modules do: macro definitions and other preprocessor states are still leaked to the consumers of the header units. You use a header unit via the <code>import \"header.h\";<\/code> or <code>import &lt;header&gt;;<\/code> syntax. In Visual Studio, the metadata for header units are automatically generated by the build system. All items declared and reasonable definitions in the header file (and its includes) are made available to the consumer, as would an <code>#include<\/code> file. Like in the case of module consumption, macro definitions and other preprocessor states active in the code that imports a header unit will not influence the imported header unit in any way. However, unlike a module, any macro definition will be available for use in your code when you import a header unit. Header units are primarily a transition mechanism, not substitute for modules. If you have a chance to consider a named module vs. a header unit, we encourage you to invest the effort in designing proper modules. We will cover header units in depth in future blogs, especially their use in migrating existing codebases to uses of modules.<\/p>\n<p>Full IDE and toolset support for header units is coming soon. You can track the status of header unit support for the Microsoft STL <a href=\"https:\/\/github.com\/microsoft\/STL\/issues\/60\">here on GitHub<\/a>.<\/p>\n<h2>Feedback<\/h2>\n<p>If you are interested in trying out C++ modules with your own code, I urge you to grab the latest Visual Studio Preview. Please try it out and let use know if you have any questions or feedback. If you find any issues or have a suggestion, the best way to reach out to us is to\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio\">Report a Problem<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++ module support has arrived in Visual Studio! Grab the latest Visual Studio Preview if you want to try it out. C++ modules can help you compartmentalize your code, speed up build times, and they work seamlessly, side-by-side with your existing code. This preview only supports C++ modules in the IDE for MSBuild projects. While [&hellip;]<\/p>\n","protected":false},"author":326,"featured_media":26952,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-26946","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>C++ module support has arrived in Visual Studio! Grab the latest Visual Studio Preview if you want to try it out. C++ modules can help you compartmentalize your code, speed up build times, and they work seamlessly, side-by-side with your existing code. This preview only supports C++ modules in the IDE for MSBuild projects. While [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/26946","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\/326"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=26946"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/26946\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/26952"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=26946"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=26946"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=26946"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}