Using C++ Modules in Visual Studio 2017

Andrew Pardoe

点这里看中文版

This post was written by Gabriel Dos Reis, Andrew Pardoe, and Billy O’Neal 

What Is New?

The Visual C++ Team is elated to announce that with Visual Studio 2017, it has substantially improved the quality of the C++ Modules TS implementation in Visual Studio, in addition to introducing ability to consume the C++ Standard Library via module interfaces.  These module interfaces for the Standard Library, just like the compiler support for modules, are experimental and will evolve to track the standardization process.

Getting Started

Standard Library Modules support is included in Visual Studio 2017 RTM or newer. This capability is currently optional and off by default. In future versions, they will be installed by default alongside the Standard Library headers. Just choose this option when installing or updating your C++ support.

Install Standard Library Modules

If you’ve already installed VS 2017 and didn’t install the Standard Library Modules, it’s easy to fix. Just rerun the installer to modify your installation options.

Rerun VS Installer

Testing Your Installation

To verify that you have VS 2017 set up to take advantage of Standard Library Modules, compile and run this simple program (say in a file test-vs2017-slm.cxx) from a Developer Command Prompt. As the feature is still experimental, there is very little built-in support in the VS IDE for modules at this point.

import std.core; 
 
int main() { 
    using namespace std; 
    vector<string> v { "Plato", "Descartes", "Bacon" }; 
    copy(v.begin(), v.end(), ostream_iterator<string>(cout, "\n")); 
} 

with the command

cl /experimental:module /EHsc /MD /std:c++latest test-vs2017-slm.cxx 

That should effortlessly produce an executable (test-vs2017-slm.exe) that, when executed, prints Plato, Descartes, and Bacon, each on a new line.

Compiler Switch for Consuming Standard Library Modules

You need to add the compiler switch /MD when compiling a source file that consumes the standard library modules. The /MD switch brings in the dynamic library for the CRT. In a debug build, you need to use /MDd instead of /MD.

If you forget to specify /MD (or /MDd for debug builds), you will get warnings from the linker and eventually a linker error LNK2019 indicating unresolved external symbols.

No other option is needed to take advantage of the Standard Library Modules support. The Standard Library modules are provided only for use with the DLL import libraries of the UCRT.

Consuming Standard Library Modules from the VS IDE

If you want to use the IDE instead of the command line, you can configure your project to use experimental modules according to the following steps.

  1. First, open Properties for the project you want to use:Open Project Properties
  2. Next, under Configuration Properties -> C/C++ -> Code Generation, verify that Multithreaded Debug DLL or Multithreaded DLL (for Debug and Release, respectively) are set. These are the default options for new projects, so if you have not changed these settings everything should work.Use dynamic libraries
  3. Next, make sure C++17 features are enabled under Configuration Properties -> C/C++ -> Language, by selecting C++17 or C++ Latest Draft Standard for any configurations you want to use.Use latest draft standard
  4. Lastly, if you are using a version of Visual Studio 2017 before 15.3, add /experimental:module /module:stdIfcDir "$(VCToolsInstallDir_150)ifc\$(PlatformTarget)" to Configuration Properties -> C/C++ -> Command Line to turn on modules for that project. Note that this step is not necessary in later updates of VS 2017: the VS IDE provides the location of the standard library modules files (the /module:stdIfcDir parameter) for you when you choose to enable C++ Modules. Also, if you’re using a compiler from a nightly NuGet package we’ve made some fixes so you should set Command Line to /experimental:module /module:stdIfcDir "$(VC_IFCPath)".Modules configuration properties

Now build and test run should succeed, showing you the names of three philosophers.

Running modules test

Module Exportation Syntax Change

At the November 2016 C++ standards meeting, the C++ standards committee changed the syntax for exporting a module (see Module Issue #1) from

export module Bank;

to

export import Bank;

This release of Visual C++ implements that resolution, in addition to allowing the old syntax with a warning. The C++ committee is considering repurposing the old syntax, with an incompatible meaning.  We encourage you to convert to the new syntax; support for the old syntax will be discontinued to implement the Module TS draft as amended by the ISO C++ standards committee.

Standard Library Modules (Experimental)

A key novelty in VS2017 RTM release is support for consuming the C++ Standard Library via modules.  This is an experimental feature and described in the C++ proposal Standard Library Modules. In this release, the modules are organized as follows:

  • std.regex provides the content of header <regex>
  • std.filesystem provides the content of header <experimental/filesystem>
  • std.memory provides the content of header <memory>
  • std.threading provodes the contents of headers <atomic>, <condition_variable>, <future>, <mutex>, <shared_mutex>, <thread>
  • std.core provides everything else in the C++ Standard Library

To use any of these modules in your program, just write import M; at toplevel in your source file, where M is any of the modules listed above. See the test example.

If you want to use modules for header other than the standard library headers, the standard library modules are produced using the /module:export switch described in the initial C++ modules blog post; with /module:export. If you have other libraries on which you depend and want to try a completely header-free experience, you can package those other headers in the same way.

Future releases will more closely track the Standard Library Modules proposal.

Call to Action

Download Visual Studio 2017 today and try out modules in your C++ projects and programs.  You can start with just replacing all #includes of standard headers for containers and algorithms with a simple import std.core; in your source files and adding the compiler switches /experimental:module and /MD or /MDd (if you’re building as debug) to your build definition.  Let us know about your experience.

In Closing

As always, we welcome your feedback. Feel free to send any comments through e-mail at visualcpp@microsoft.com, through Twitter @visualc, or Facebook at Microsoft Visual Cpp.

If you encounter other problems with MSVC in VS 2017 please let us know via the Report a Problem option, either from the installer or the Visual Studio IDE itself. For suggestions, let us know through UserVoice. Thank you!

0 comments

Discussion is closed.

Feedback usabilla icon