{"id":7311,"date":"2015-12-03T10:21:00","date_gmt":"2015-12-03T10:21:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2015\/12\/03\/c-modules-in-vs-2015-update-1\/"},"modified":"2019-02-18T18:04:54","modified_gmt":"2019-02-18T18:04:54","slug":"c-modules-in-vs-2015-update-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/c-modules-in-vs-2015-update-1\/","title":{"rendered":"C++ Modules in VS 2015 Update 1"},"content":{"rendered":"<p><a href=\"https:\/\/blogs.msdn.microsoft.com\/c\/2015\/12\/16\/vs-2015-update-1cmodules\/\">\u70b9\u8fd9\u91cc\u770b\u4e2d\u6587\u7248<\/a><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">[This post was written by Gabriel Dos Reis and Andrew Pardoe]<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><strong>Update: See this post on <a href=\"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2017\/05\/05\/cpp-modules-in-visual-studio-2017\/\">using the Standard Library via modules in MSVC<\/a>.<\/strong><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">The VC++ team is excited to preview a new feature in VS 2015 Update 1: The first experimental implementation of<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><em><a target=\"_blank\" href=\"http:\/\/www.open-std.org\/JTC1\/SC22\/WG21\/docs\/papers\/2015\/n4465.pdf\">A Module System for C++<\/a><\/em><span style=\"color: #000000\">, proposed for C++17. That proposal was approved by the C++ standards Evolution Working Group for a C++17 Technical Specification at the Fall 2015 meeting in Kona, Hawai\u2019i. The<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><a target=\"_blank\" href=\"https:\/\/isocpp.org\/blog\/2015\/12\/p0143r0\">draft wording for the Technical Specification<\/a><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>is under review by the C++ Standards Core Working Group.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">Modules are often talked about as a way to speed up compilation. But they have far more to offer than just build performance! C++ Modules can help you improve componentization of your code. In fact, componentization is an effective road to compilation and build throughput. Modules allow you to isolate your code from hard-to-debug preprocessor state. And they make it easier to develop tools to work with your code.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">Modules allow you to express the symbolic dependency your component is taking on providers of functionalities it needs, and the boundary of that dependency, directly in code. Modules eliminate the need for convoluted preprocessor voodoo to specify interfaces through header files. The preprocessor is there for you and works together with the modules system if you have no other choice but to work with macro-based interfaces, conditional compilation and code-generation. The preprocessor is a powerful beast with no structure and C++ Modules aren\u2019t designed to do everything that it does. The preprocessor\u2019s job is to generate pre-tokens for the lexer to consume. It has been put to creative usages, for more than 40 years, to generate various sorts of text, including HTML source documents.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">If you want to know more about the principles and rationale behind the design choices of C++ Modules, stop now and read the proposal:<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><em><a target=\"_blank\" href=\"http:\/\/www.open-std.org\/JTC1\/SC22\/WG21\/docs\/papers\/2015\/n4465.pdf\">A Module System for C++<\/a><\/em>\u00a0<span style=\"color: #000000\">.There\u2019s also a great talk on C++ Modules by Gabriel Dos Reis from CppCon 2015. The video is on the<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><a target=\"_blank\" href=\"https:\/\/www.youtube.com\/user\/CppCon\">CppCon YouTube channel<\/a><span style=\"color: #000000\">; the slides from the talk are also available in an<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><a target=\"_blank\" href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/talks\/Large-Scale-C%2B%2B-With-Modules.pdf\">IsoCpp GitHub repo<\/a><span style=\"color: #000000\">. But if you want to jump right in and see what this feature has to offer, read on!<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\"><strong>The implementation in Visual C++ 2015 Update 1 is a preview of an ongoing effort so we\u2019re eager to hear your feedback.<\/strong><span class=\"Apple-converted-space\">\u00a0<\/span>This is a chance for you to have impact on a major C++ feature. We want to build a C++ modules system that works for all developers with all compilers so please let us know if you have any feedback. You can reach us at<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><a target=\"_blank\" href=\"mailto:modules@microsoft.com\">modules@microsoft.com<\/a>.<\/p>\n<h2 id=\"modules-support-in-visual-c-2015-update-1\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Modules Support in Visual C++ 2015 Update 1<\/span><\/h2>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">First, you should know that module support is completely guarded by a switch:<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/experimental:module<\/em>. If you don\u2019t use this switch then the modules feature won\u2019t affect your code at all. Also, be aware that support for modules is only in the command-line tools right now. A lot of IDE functionality should just work but full IDE integration isn&#8217;t there yet. Also, this preview\u2019s focus is on componentization. As we advance in completing support for C++ language features, we will be increasing our focus to optimizing build throughput in the module support; without componentization first, it would be far too easy to duplicate a particular build logic without making significant dents into the fundamental problems.<\/span><\/p>\n<h3 id=\"producing-modules\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Producing Modules<\/span><\/h3>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">Creating and using a module is straightforward: the developer merely declares a source file to contain the definition of a module by writing<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">module M;<\/code><span style=\"color: #000000\">. She then announces what parts of the source file are part of the module\u2019s interface by preceding each and every single declaration of those entities with the<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">export<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>keyword.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">Any top-level declaration can be exported or any sequence of top-level declarations contained in braces. Modules do not define new namespaces or change name lookup rules in any way. They simply allow the developer to specify and publish the interface for a source file. So, there is really no new name lookup rules you need to learn.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">In this example, the functions<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">f(int)<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>and<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">g(double, int)<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>are exported as part of the interface of<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">module M<\/code><span style=\"color: #000000\">.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\"><span style=\"color: #000000\"><span style=\"color: #000000;font-family: terminal,monaco\"><span class=\"token\" style=\"color: #339966\">\/\/ file: foo.ixx<\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">module <span style=\"color: #000000\">M;<\/span>\nexport int<\/span> f(<span style=\"color: #3366ff\">int<\/span> <span style=\"color: #999999\">x<\/span>) <\/span>\n<span class=\"token\" style=\"color: #000000\">{ <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">\u00a0\u00a0\u00a0 return<\/span> 2 + <span style=\"color: #999999\">x<\/span>; <\/span>\n<span class=\"token\" style=\"color: #000000\">} <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">export double<\/span> g(<span style=\"color: #3366ff\">double<\/span> <span style=\"color: #999999\">y<\/span>, <span style=\"color: #3366ff\">int <\/span><span style=\"color: #999999\">z<\/span>) <\/span>\n<span class=\"token\" style=\"color: #000000\">{ <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">\u00a0\u00a0\u00a0 return<\/span> <span style=\"color: #999999\">y<\/span> * <span style=\"color: #999999\">z<\/span>; <\/span>\n<span class=\"token\" style=\"color: #000000\">} <\/span><\/span><\/span><\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">The command line to compile the module interface is just<span class=\"Apple-converted-space\">\u00a0<\/span><em>cl \/c \/experimental:module foo.ixx<\/em>. The extension &#8220;ixx&#8221; is special. It tells the compiler that the content of the source file is supposed to be a module interface source code. If you want to use another extension on your interface file you also have to supply the switch<em>\/module:interface<\/em>. (Note these switches are subject to change in the future!)<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">When you compile a module interface file, you get an OBJ file as usual. The compiler also produces a file with extension &#8220;.ifc&#8221;(called an<span class=\"Apple-converted-space\">\u00a0<\/span><em>IFC file<\/em>) that contains a metadata description of the module interface. This is the only time that the module support produces anything additional to what a traditional compilation would do. The binary format of the IFC file will be open source; it is modelled after the<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><em><a target=\"_blank\" href=\"http:\/\/www.stroustrup.com\/gdr-bs-macis09.pdf\">Internal Program Representation<\/a><\/em><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>work done by Gabriel Dos Reis and Bjarne Stroustrup a decade ago. The original implementation of the IPR is open source and can be found in the<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><a target=\"_blank\" href=\"https:\/\/github.com\/GabrielDosReis\/ipr\">IPR repo on GitHub<\/a><span style=\"color: #000000\">.<\/span><\/p>\n<h3 id=\"consuming-modules\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Consuming Modules<\/span><\/h3>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\"><a><\/a>To consume the module, the developer writes<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">import M;<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>at the top of a source file, thus making the declarations of<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">f(int)<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>and<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">g(double, int)<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>visible in the source file. The compiler switch to specify a compiled binary module interface file is<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:reference<\/em>.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\"><span style=\"color: #000000\"><span style=\"color: #000000;font-family: terminal,monaco\"><span class=\"token\" style=\"color: #339966\">\/\/ file: bar.cpp<\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">import<\/span>\u00a0M;\n<\/span><span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">int <span style=\"color: #000000\">main()<\/span><\/span><\/span>\n<span class=\"token\" style=\"color: #000000\">{\nf(5);\ng(0.0, 1);<\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">\u00a0\u00a0\u00a0 return<\/span> 0; <\/span>\n<span class=\"token\" style=\"color: #000000\">} <\/span><\/span><\/span><\/span><\/p>\n<p><span style=\"color: #000000\">Compile bar.cpp with the command line<span class=\"Apple-converted-space\">\u00a0<\/span><em>cl \/experimental:module \/module:reference M.ifc bar.cpp foo.obj<\/em>. The function definitions for<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">f(int)<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>and<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">g(double, int)<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>are available in bar.cpp because of the import statement. If there are too many reference files, or if you put all your IFC files in a given directory, you can instead use the compiler option<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:search<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>which takes a directory name as its argument.<\/span><\/p>\n<h3 id=\"overview\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Overview<\/span><\/h3>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">At the file level, the source file containing the module definition is called foo.ixx. (The name of the module definition, M in our example, doesn\u2019t need to match the name of the file, foo.) Compiling foo.ixx creates M.ifc, the module interface file, which is a binary representation of the interface, in addition to foo.obj, the standard Windows object file.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">When consuming a module (with the<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:reference<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>switch), the compiler reads in M.ifc to make the top-level exported names in the interface available to the source file currently being compiled, and the linker consumes foo.obj as usual.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">These three keywords and two switches are enough to let you experiment with C++ Modules. There are a few more switches available for transitional scenarios but they\u2019re not something to depend upon as they might change as the design evolves.<\/span><\/p>\n<p>Edit 4 Oct 2016: We&#8217;ve had some interest in specifying the output directory and interface file name. That option is simply \/module:output, as follows:\n<span style=\"color: #000000;font-family: Calibri\">\u00a0\u00a0cl \/experimental:module \/module:export \/module:name ModuleName \/module:wrapper C:\\Output\\path\\ModuleName.h <\/span><span><span style=\"color: #000000;font-family: Calibri\">\/module:output C:\\Output\\path\\ModuleName.ifc<\/span><\/span><span style=\"color: #000000;font-family: Calibri\"> -c &lt;source-file&gt;<\/span><\/p>\n<h2 id=\"convenience-functions\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Convenience Functions<\/span><\/h2>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">It&#8217;s important that C++ Modules be incrementally adoptable in your source code. We&#8217;ve created a few convenience functions to help with migration scenarios. All of these functions are being tested by teams inside of Microsoft. They will likely change based on internal and external developer feedback. We&#8217;ve also created some tooling to help manipulate module interface files that we&#8217;ll discuss in another blog post.<\/span><\/p>\n<h3 id=\"consuming-existing-legacy-header-files-as-module-interfaces\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Consuming Existing Legacy Header Files as Module Interfaces<\/span><\/h3>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">Say you have an existing source file (in particular header file) that is well-behaved in terms of macros and preprocessor state. You&#8217;d like to make that header consumable as if it was a module interface. We&#8217;ve build a convenience into the compiler that allows you to pretend that all top-level declarations with external linkage in a C++ source file were marked as exported. You use the switches<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:name<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>and<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:export<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>to automatically create a compiled module interface (IFC) from a header. The argument to<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:name<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>specifies the name of the module interface (.IFC) and the argument to<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:export<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>specifies which header file should be consumed to create the module interface. Note that you currently have to include your header in a .cpp file (or rename your header) because of a limitation in our compiler&#8217;s file handling.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\"><span style=\"color: #000000;font-family: terminal,monaco\"><span class=\"token\" style=\"color: #339966\">\/\/ file: foo.cpp<\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">int<\/span> f(<span style=\"color: #3366ff\">int<\/span> <span style=\"color: #999999\">x<\/span>) <\/span>\n<span class=\"token\" style=\"color: #000000\">{ <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">\u00a0\u00a0\u00a0 return<\/span> 2 + <span style=\"color: #999999\">x<\/span>; <\/span>\n<span class=\"token\" style=\"color: #000000\">} <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">double<\/span> g(<span style=\"color: #3366ff\">double<\/span> <span style=\"color: #999999\">y<\/span>, <span style=\"color: #3366ff\">int <\/span><span style=\"color: #999999\">z<\/span>) <\/span>\n<span class=\"token\" style=\"color: #000000\">{ <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">\u00a0\u00a0\u00a0 return<\/span> <span style=\"color: #999999\">y<\/span> * <span style=\"color: #999999\">z<\/span>; <\/span>\n<span class=\"token\" style=\"color: #000000\">} <\/span><\/span><\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">The command line<span class=\"Apple-converted-space\">\u00a0<\/span><em>cl \/c \/experimental:module \/module:name mymodule \/module:export foo.cpp<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>produces mymodule.ifc, an interface file with definitions for<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">f(int)<\/code><span style=\"color: #000000\"><span class=\"Apple-converted-space\">\u00a0<\/span>and <\/span><code style=\"color: #d7ba7d;line-height: 19px;font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', 'Courier New', monospace, 'Droid Sans Fallback';font-size: 14px\">g(double, int)<\/code><span style=\"color: #000000\">.<\/span><\/p>\n<h3 id=\"module-search-path\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Module Search Path<\/span><\/h3>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\"><em>\/module:search<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>indicates a directory where the compiler should search for files referenced via<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:reference<\/em>. For example, the compilation command line for bar.cpp above (in<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><a>Consuming Modules<\/a><span style=\"color: #000000\">) could have been written as<span class=\"Apple-converted-space\">\u00a0<\/span><em>cl \/experimental:module \/module:search . bar.cpp foo.obj<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>to search the current directory for the IFC file.<\/span><\/p>\n<h3 id=\"preserving-macros\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Preserving Macros<\/span><\/h3>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">Lastly, if your legacy source file defines macros that are essential to its consumers, you can have the compiler generate a wrapper header file containing an import declaration followed by a preprocessor definition of those macros. The compiler switch<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:exportActiveMacros<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>exports all macro definitions that are active when the compiler finishes compiling the source file that defines the module. If you want to be selective you can use<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:exportMacro<span class=\"Apple-converted-space\">\u00a0<\/span><\/em>instead, where<span class=\"Apple-converted-space\">\u00a0<\/span><em><\/em>designates the macro you want to be defined in the wrapper file. The name of the wrapper header file is specified via the switch<span class=\"Apple-converted-space\">\u00a0<\/span><em>\/module:wrapper<\/em><span class=\"Apple-converted-space\">\u00a0<\/span>which takes a filename argument.<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000;font-family: terminal,monaco\"><span class=\"token\" style=\"color: #339966\">\/\/ file: baz.h<\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #999999\">#ifndef<\/span> BAR_INCLUDED<\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #999999\">#define<\/span> <span style=\"color: #800080\">number<\/span> 6<\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">int<\/span> f(<span style=\"color: #3366ff\">int<\/span> <span style=\"color: #999999\">x<\/span>) <\/span>\n<span class=\"token\" style=\"color: #000000\">{ <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">\u00a0\u00a0\u00a0 return<\/span> 2 + <span style=\"color: #999999\">x<\/span>; <\/span>\n<span class=\"token\" style=\"color: #000000\">} <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">double<\/span> g(<span style=\"color: #3366ff\">double<\/span> <span style=\"color: #999999\">y<\/span>, <span style=\"color: #3366ff\">int <\/span><span style=\"color: #999999\">z<\/span>) <\/span>\n<span class=\"token\" style=\"color: #000000\">{ <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #3366ff\">\u00a0\u00a0\u00a0 return<\/span> <span style=\"color: #999999\">y<\/span> * <span style=\"color: #999999\">z<\/span>; <\/span>\n<span class=\"token\" style=\"color: #000000\">} <\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #999999\">#endif<\/span> <span style=\"color: #339966\">\/\/ BAR_INCLUDED<\/span><\/span><\/span><\/p>\n<p><span class=\"token\" style=\"color: #339966\">\/\/ file: baz.cpp<\/span>\n<span class=\"token\" style=\"color: #000000\"><span style=\"color: #999999\">#include<\/span> \u201cbaz.h\u201d<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">Compiling the above source files with<span class=\"Apple-converted-space\">\u00a0<\/span><em>cl \/c \/experimental:module \/module:export \/module:name mymodule baz.cpp \/module:wrapper baz-wrapper.h \/module:exportActiveMacros <\/em>will produce mymodule.ifc, as expected, but will additionally produce a header file, baz-wrapper.h, containing the following:<\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000;font-family: terminal,monaco\"><span class=\"token\" style=\"color: #000000;background-color: #ffffff\"><span style=\"color: #999999\">#ifndef<\/span> mymodule_WRAPPER_INCLUDED<\/span>\n<span class=\"token\" style=\"color: #000000;background-color: #ffffff\"><span style=\"color: #999999\">#define<\/span> <span style=\"color: #800080\">mymodule_WRAPPER_INCLUDED<\/span><\/span>\n<span class=\"token\" style=\"color: #000000;background-color: #ffffff\">import mymodule;<\/span>\n<span class=\"token\" style=\"color: #000000;background-color: #ffffff\"><span style=\"color: #999999\">#define<\/span> <span style=\"color: #800080\">number<\/span> 6<\/span>\n<span class=\"token\" style=\"color: #000000;background-color: #ffffff\"><span style=\"color: #999999\">#endif<\/span> <span style=\"color: #339966\">\/\/ mymodule_WRAPPER_INCLUDED<\/span><\/span><\/span><\/p>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">You can now include baz-wrapper.h instead of baz.h and get the componentization benefits of modules even if baz.h wasn\u2019t written as a module in the first place. This technique preserves your preprocessor state and gives you a chance to clean up any macros that you might not have realized were active at the time. Sadly, sorting through rogue preprocessor state is an all too common experience.<\/span><\/p>\n<h2 id=\"have-fun-\" style=\"color: #dddddd;line-height: 22px;text-indent: 0px;letter-spacing: normal;font-family: 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';font-style: normal;font-variant: normal;font-weight: 400\"><span style=\"color: #000000\">Have Fun!<\/span><\/h2>\n<p style=\"font: 14px\/22px 'Segoe WPC', 'Segoe UI', SFUIText-Light, HelveticaNeue-Light, sans-serif, 'Droid Sans Fallback';color: #dddddd;text-indent: 0px;letter-spacing: normal\"><span style=\"color: #000000\">C++ Modules in VS 2015 Update 1 are an exciting feature, even in this early state. There\u2019s more goodness to come\u2014obviously we\u2019re lacking some basic functionality such as integration with the VS IDE and build system\u2014but we wanted to get something out there early so that our developer community could have a chance to impact the work in a big way. Please try out C++ Modules and let us know your thoughts at<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><a target=\"_blank\" href=\"mailto:modules@microsoft.com\">modules@microsoft.com<\/a><span style=\"color: #000000\">.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u70b9\u8fd9\u91cc\u770b\u4e2d\u6587\u7248 [This post was written by Gabriel Dos Reis and Andrew Pardoe] Update: See this post on using the Standard Library via modules in MSVC. The VC++ team is excited to preview a new feature in VS 2015 Update 1: The first experimental implementation of\u00a0A Module System for C++, proposed for C++17. That proposal was [&hellip;]<\/p>\n","protected":false},"author":312,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[48,140,100,151,246],"class_list":["post-7311","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-build","tag-c","tag-c-language","tag-iso-c","tag-modules"],"acf":[],"blog_post_summary":"<p>\u70b9\u8fd9\u91cc\u770b\u4e2d\u6587\u7248 [This post was written by Gabriel Dos Reis and Andrew Pardoe] Update: See this post on using the Standard Library via modules in MSVC. The VC++ team is excited to preview a new feature in VS 2015 Update 1: The first experimental implementation of\u00a0A Module System for C++, proposed for C++17. That proposal was [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/7311","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\/312"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=7311"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/7311\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=7311"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=7311"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=7311"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}