Skip to content

Commit 902a88b

Browse files
Merge pull request #4920 from MicrosoftDocs/main638423221370915491sync_temp
For protected branch, push strategy should use PR and merge to target branch method to work around git push error
2 parents ef302a1 + b89bf9b commit 902a88b

File tree

2 files changed

+38
-30
lines changed

2 files changed

+38
-30
lines changed

docs/cpp/modules-cpp.md

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
---
22
title: "Overview of modules in C++"
3-
ms.date: 04/24/2023
3+
ms.date: 01/29/2024
44
helpviewer_keywords: ["modules [C++]", "modules [C++], overview"]
55
description: Modules in C++20 provide a modern alternative to header files.
66
---
77
# Overview of modules in C++
88

9-
C++20 introduces *modules*, a modern solution that turns C++ libraries and programs into components. A *module* is a set of source code files that are compiled independently of the source files (or more precisely, the [translation units](https://wikipedia.org/wiki/Translation_unit_(programming)) that import them). Modules eliminate or reduce many of the problems associated with the use of header files. They often reduce compilation times. Macros, preprocessor directives, and nonexported names declared in a module aren't visible outside the module. They have no effect on the compilation of the translation unit that imports the module. You can import modules in any order without concern for macro redefinitions. Declarations in the importing translation unit don't participate in overload resolution or name lookup in the imported module. After a module is compiled once, the results are stored in a binary file that describes all the exported types, functions, and templates. The compiler can process that file much faster than a header file. And, the compiler can reuse it every place where the module is imported in a project.
9+
C++20 introduces *modules*. A *module* is a set of source code files that are compiled independently of the source files (or more precisely, the [translation units](https://wikipedia.org/wiki/Translation_unit_(programming)) that import them.
10+
11+
Modules eliminate or reduce many of the problems associated with the use of header files. They often reduce compilation times, sometimes significantly. Macros, preprocessor directives, and nonexported names declared in a module aren't visible outside the module. They have no effect on the compilation of the translation unit that imports the module. You can import modules in any order without concern for macro redefinitions. Declarations in the importing translation unit don't participate in overload resolution or name lookup in the imported module. After a module is compiled once, the results are stored in a binary file that describes all the exported types, functions, and templates. The compiler can process that file much faster than a header file. And, the compiler can reuse it every place where the module is imported in a project.
1012

1113
You can use modules side by side with header files. A C++ source file can `import` modules and also `#include` header files. In some cases, you can import a header file as a module, which is faster than using `#include` to process it with the preprocessor. We recommend that you use modules in new projects rather than header files as much as possible. For larger existing projects under active development, experiment with converting legacy headers to modules. Base your adoption on whether you get a meaningful reduction in compilation times.
1214

@@ -43,11 +45,13 @@ import std.core;
4345
import std.regex;
4446
```
4547

46-
To consume the Microsoft Standard Library modules, compile your program with [`/EHsc`](../build/reference/eh-exception-handling-model.md) and [`/MD`](../build/reference/md-mt-ld-use-run-time-library.md) options.
48+
To consume the Microsoft Standard Library modules, compile your program with the [`/EHsc`](../build/reference/eh-exception-handling-model.md) and [`/MD`](../build/reference/md-mt-ld-use-run-time-library.md) options.
4749

4850
## Example
4951

50-
The following example shows a simple module definition in a source file called *`Example.ixx`*. The *`.ixx`* extension is required for module interface files in Visual Studio. In this example, the interface file contains both the function definition and the declaration. However, you can also place the definitions in one or more separate module implementation files, as shown in a later example. The `export module Example;` statement indicates that this file is the primary interface for a module called `Example`. The **`export`** modifier on `f()` indicates that this function is visible when another program or module imports `Example`. The module references a namespace `Example_NS`.
52+
The following example shows a simple module definition in a source file called *`Example.ixx`*. The *`.ixx`* extension is required for module interface files in Visual Studio. In this example, the interface file contains both the function definition and the declaration. However, you can also place the definitions in one or more separate module implementation files, as shown in a later example.
53+
54+
The `export module Example;` statement indicates that this file is the primary interface for a module called `Example`. The **`export`** modifier on `f()` indicates that this function is visible when another program or module imports `Example`.
5155

5256
```cpp
5357
// Example.ixx
@@ -67,7 +71,7 @@ namespace Example_NS
6771
}
6872
```
6973

70-
The file *`MyProgram.cpp`* uses the **`import`** declaration to access the name that is exported by `Example`. The name `Example_NS` is visible here, but not all of its members. Also, the macro `ANSWER` isn't visible.
74+
The file *`MyProgram.cpp`* uses **`import`** to access the name exported by `Example`. The namespace name `Example_NS` is visible here, but not all of its members because they aren't exported. Also, the macro `ANSWER` isn't visible because macros aren't exported.
7175

7276
```cpp
7377
// MyProgram.cpp
@@ -109,64 +113,68 @@ The `import` declaration can appear only at global scope.
109113
110114
## Implementing modules
111115

112-
A *module interface* exports the module name and all the namespaces, types, functions, and so on, that make up the public interface of the module. A *module implementation* defines the things exported by the module. In its simplest form, a module can consist of a single file that combines the module interface and implementation. You can also put the implementation in one or more separate module implementation files, similar to how *`.h`* and *`.cpp`* files do it.
116+
A *module interface* exports the module name and all the namespaces, types, functions, and so on, that make up the public interface of the module.\
117+
A *module implementation* defines the things exported by the module.\
118+
In its simplest form, a module can be a single file that combines the module interface and implementation. You can also put the implementation in one or more separate module implementation files, similar to how *`.h`* and *`.cpp`* files do it.
113119

114-
For larger modules, you can split parts of the module into submodules called *partitions*. Each partition consists of a module interface file that exports a module partition name. A partition may also have one or more partition implementation files. The module as a whole has one *primary module interface*, which is the public interface of the module and may export the partition interfaces.
120+
For larger modules, you can split parts of the module into submodules called *partitions*. Each partition consists of a module interface file that exports the module partition name. A partition may also have one or more partition implementation files. The module as a whole has one *primary module interface*, which is the public interface of the module. It can export the partition interfaces, if desired.
115121

116122
A module consists of one or more *module units*. A module unit is a translation unit (a source file) that contains a module declaration. There are several types of module units:
117123

118-
- A *module interface unit* is a module unit that exports a module name or module partition name. A module interface unit has `export module` in its module declaration.
119-
120-
- A *module implementation unit* is a module unit that doesn't export a module name or module partition name. As the name implies, it implements a module.
121-
122-
- A *primary module interface unit* is a module interface unit that exports the module name. There must be one and only one primary module interface unit in a module.
124+
- A *module interface unit* exports a module name or module partition name. A module interface unit has `export module` in its module declaration.
125+
- A *module implementation unit* doesn't export a module name or module partition name. As the name implies, it implements a module.
126+
- A *primary module interface unit* exports the module name. There must be one and only one primary module interface unit in a module.
127+
- A *module partition interface unit* exports a module partition name.
128+
- A *module partition implementation unit* has a module partition name in its module declaration, but no `export` keyword.
123129

124-
- A *module partition interface unit* is a module interface unit that exports a module partition name.
125-
126-
- A *module partition implementation unit* is a module implementation unit that has a module partition name in its module declaration, but no `export` keyword.
127-
128-
The **`export`** keyword is used in interface files only. An implementation file can **`import`** another module, but can't **`export`** any names. Implementation files can have any extension.
130+
The **`export`** keyword is only used in interface files. An implementation file can **`import`** another module, but it can't **`export`** any names. Implementation files can have any extension.
129131

130132
## Modules, namespaces, and argument-dependent lookup
131133

132-
The rules for namespaces in modules are the same as in any other code. If a declaration within a namespace is exported, the enclosing namespace (excluding nonexported members) is also implicitly exported. If a namespace is explicitly exported, all declarations within that namespace definition are exported.
134+
The rules for namespaces in modules are the same as any other code. If a declaration within a namespace is exported, the enclosing namespace (excluding members that aren't explicitly exported in that namespace) is also implicitly exported. If a namespace is explicitly exported, all declarations within that namespace definition are exported.
133135

134136
When the compiler does argument-dependent lookup for overload resolutions in the importing translation unit, it considers functions declared in the same translation unit (including module interfaces) as where the type of the function's arguments are defined.
135137

136138
### Module partitions
137139

138-
A module partition is similar to a module, except it shares ownership of all declarations in the entire module. All names exported by partition interface files are imported and re-exported by the primary interface file. A partition's name must begin with the module name followed by a colon. Declarations in any of the partitions are visible within the entire module. No special precautions are needed to avoid one-definition-rule (ODR) errors. You can declare a name (function, class, and so on) in one partition and define it in another. A partition implementation file begins like this:
140+
A module partition is similar to a module, except:
141+
- It shares ownership of all declarations in the entire module.
142+
- All names exported by partition interface files are imported and exported by the primary interface file.
143+
- A partition's name must begin with the module name followed by a colon (`:`).
144+
- Declarations in any of the partitions are visible within the entire module.\
145+
- No special precautions are needed to avoid one-definition-rule (ODR) errors. You can declare a name (function, class, and so on) in one partition and define it in another.
146+
147+
A partition implementation file begins like this, and is an internal partition from a C++ standards perspective:
139148

140149
```cpp
141150
module Example:part1;
142151
```
143152

144-
The partition interface file begins like this:
153+
A partition interface file begins like this:
145154

146155
```cpp
147156
export module Example:part1;
148157
```
149158

150-
To access declarations in another partition, a partition must import it, but it can only use the partition name, not the module name:
159+
To access declarations in another partition, a partition must import it. But it can only use the partition name, not the module name:
151160

152161
```cpp
153162
module Example:part2;
154163
import :part1;
155164
```
156165

157-
The primary interface unit must import and re-export all of the module's interface partition files like this:
166+
The primary interface unit must import and re-export all of the module's interface partition files, like this:
158167

159168
```cpp
160169
export import :part1;
161170
export import :part2;
162-
...
163171
```
164172

165173
The primary interface unit can import partition implementation files, but can't export them. Those files aren't allowed to export any names. This restriction enables a module to keep implementation details internal to the module.
166174

167175
## Modules and header files
168176

169-
You can include header files in a module source file by putting the `#include` directive before the module declaration. These files are considered to be in the *global module fragment*. A module can only see the names in the global module fragment that are in headers it explicitly includes. The global module fragment only contains symbols that are used.
177+
You can include header files in a module source file by putting an `#include` directive before the module declaration. These files are considered to be in the *global module fragment*. A module can only see the names in the global module fragment that are in the headers that it explicitly includes. The global module fragment only contains symbols that are used.
170178

171179
```cpp
172180
// MyModuleA.cpp

docs/cpp/tutorial-named-modules-cpp.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,19 @@ This line identifies this file as the primary module interface and gives the mod
9292

9393
This name is also where the "named" in "named module" comes from. The files that are part of this module use this name to identify themselves as part of the named module. A named module is the collection of module units with the same module name.
9494

95-
We should talk about the API we'll implement for a moment before going further. It impacts the choices we make next. The API represents different shapes. We're only going to provide a couple shapes in this example: `Point` and `Rectangle`. `Point` is meant to be used as part of more complex shapes, such as `Rectangle`.
95+
We should talk about the API we'll implement for a moment before going further. It impacts the choices we make next. The API represents different shapes. We're only going to provide a couple shapes in this example: `Point` and `Rectangle`. `Point` is meant to be used as part of more complex shapes such as `Rectangle`.
9696

9797
To illustrate some features of modules, we'll factor this API into pieces. One piece will be the `Point` API. The other part will be `Rectangle`. Imagine that this API will grow into something more complex. The division is useful for separating concerns or easing code maintenance.
9898

99-
So far, we've created the primary module interface that will expose this API. Let's now build the `Point` API. We want it to be part of this module. For reasons of logical organization, and potential build efficiency, we want to make this part of the API easily understandable on its own. To do so, we'll create a *module partition* file.
99+
So far, we've created the primary module interface that will expose this API. Let's now build the `Point` API. We want it to be part of this module. For reasons of logical organization, and potential build efficiency, we want to make the code for this part of the API a *module partition* file.
100100

101-
A module partition file is a piece, or component, of a module. What makes it unique is that it can be treated as an individual piece of the module, but only within the module. Module partitions can't be consumed outside of a module. Module partitions are useful for dividing the module implementation into manageable pieces.
101+
Module partitions are useful for dividing the module implementation into manageable pieces. A module partition file is a piece, or component, of a module. What makes it unique is that it can be treated as an individual piece of the module--but only within the module. Module partitions can't be consumed outside of a module.
102102

103103
When you import a partition into the primary module, all its declarations become visible to the primary module regardless of whether they're exported. Partitions can be imported into any partition interface, primary module interface, or module unit that belongs to the named module.
104104

105105
## Create a module partition file
106106

107-
### `Point` module partition
107+
### `Point` module partition example
108108

109109
To create a module partition file, in the **Solution Explorer** right-click **Source Files**, then select **Add** > **Module**. Name the file *`BasicPlane.Figures-Point.ixx`* and choose **Add**.
110110

@@ -123,11 +123,11 @@ export struct Point
123123

124124
The file starts with `export module`. These keywords are also how the primary module interface begins. What makes this file different is the colon (`:`) following the module name, followed by the partition name. This naming convention identifies the file as a *module partition*. Because it defines the module interface for a partition, it isn't considered the primary module interface.
125125

126-
The name `BasicPlane.Figures:Point` identifies this partition as part of the module `BasicPlane.Figures`. (Remember, the period in the name has no special meaning to the compiler). The colon indicates that this file contains a module partition named `Point` that belongs to the module `BasicPlane.Figures`. We can import this partition into other files that are part of this named module.
126+
The name `BasicPlane.Figures:Point` identifies this partition as part of the module `BasicPlane.Figures` (remember, the period in the name has no special meaning to the compiler). The colon indicates that this file contains a module partition named `Point` that belongs to the module `BasicPlane.Figures`. We can import this partition into other files that are part of this named module.
127127

128128
In this file, the `export` keyword makes `struct Point` visible to consumers.
129129

130-
### `Rectangle` module partition
130+
### `Rectangle` module partition example
131131

132132
The next partition we'll define is `Rectangle`. Create another module file using the same steps as before: In **Solution Explorer**, right-click on **Source Files**, then select **Add** > **Module**. Name the file *`BasicPlane.Figures-Rectangle.ixx`* and select **Add**.
133133

0 commit comments

Comments
 (0)