Skip to content

Commit ab45b50

Browse files
authored
Merge pull request #4197 from corob-msft/docs/corob/cpp-docs-220315
Fixes for GitHub issues March edition
2 parents ee00e8c + 1f11bde commit ab45b50

File tree

4 files changed

+65
-32
lines changed

4 files changed

+65
-32
lines changed

docs/cpp/modules-cpp.md

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
22
title: "Overview of modules in C++"
3-
ms.date: 02/14/2022
3+
ms.date: 03/30/2022
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 for componentization of C++ libraries and programs. A module is a set of source code files that are compiled independently of 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 non-exported 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. That file can be processed 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 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 [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 non-exported 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.
1010

11-
Modules can be used side by side with header files. A C++ source file can import modules and also #include header files. In some cases, a header file can be imported as a module rather than textually #included by the preprocessor. We recommend 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 adoption on whether you get a meaningful reduction in compilation times.
11+
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 rather than include it textually by using `#include` in the preprocessor. We recommend 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.
1212

1313
## Enable modules in the Microsoft C++ compiler
1414

@@ -18,7 +18,7 @@ A module and the code that consumes it must be compiled with the same compiler o
1818

1919
## Consume the C++ Standard Library as modules
2020

21-
Although not specified by the C++20 standard, Microsoft enables its implementation of the C++ Standard Library to be imported as modules. By importing the C++ Standard Library as modules rather than #including it through header files, you can potentially speed up compilation times depending on the size of your project. The library is componentized into the following modules:
21+
Although not specified by the C++20 standard, Microsoft makes its implementation of the C++ Standard Library importable as modules. By importing the C++ Standard Library as modules rather than including it through header files, you can potentially speed up compilation times depending on the size of your project. The library is split into the following named modules:
2222

2323
- `std.regex` provides the content of header `<regex>`
2424
- `std.filesystem` provides the content of header `<filesystem>`
@@ -33,13 +33,14 @@ import std.core;
3333
import std.regex;
3434
```
3535

36-
To consume the Microsoft Standard Library module, 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.
36+
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.
3737

3838
## Basic example
3939

40-
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, the definitions can be also placed in one or more separate 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 `Example` is imported by another program or module. The module references a namespace `Example_NS`.
40+
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 `Example` is imported by another program or module. The module references a namespace `Example_NS`.
4141

4242
```cpp
43+
// Example.ixx
4344
export module Example;
4445

4546
#define ANSWER 42
@@ -59,7 +60,7 @@ namespace Example_NS
5960
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.
6061

6162
```cpp
62-
63+
// MyProgram.cpp
6364
import Example;
6465
import std.core;
6566

@@ -71,16 +72,50 @@ int main()
7172
// int i = Example_NS::f_internal(); // C2039
7273
// int j = ANSWER; //C2065
7374
}
74-
7575
```
7676

7777
The `import` declaration can appear only at global scope.
7878

79+
## Module grammar
80+
81+
> *`module-name`*:\
82+
> &emsp;*`module-name-qualifier-seq`*<sub>opt</sub> *`identifier`*
83+
>
84+
> *`module-name-qualifier-seq`*:\
85+
> &emsp;*`identifier`* **`.`**\
86+
> &emsp;*`module-name-qualifier-seq`* *`identifier`* **`.`**
87+
>
88+
> *`module-partition`*:\
89+
> &emsp;**`:`** *`module-name`*
90+
>
91+
> *`module-declaration`*:\
92+
> &emsp;**`export`**<sub>opt</sub> **`module`** *`module-name`* *`module-partition`*<sub>opt</sub> *`attribute-specifier-seq`*<sub>opt</sub> **`;`**
93+
>
94+
> *`module-import-declaration`*:\
95+
> &emsp;**`export`**<sub>opt</sub> **`import`** *`module-name`* *`attribute-specifier-seq`*<sub>opt</sub> **`;`**\
96+
> &emsp;**`export`**<sub>opt</sub> **`import`** *`module-partition`* *`attribute-specifier-seq`*<sub>opt</sub> **`;`**\
97+
> &emsp;**`export`**<sub>opt</sub> **`import`** *`header-name`* *`attribute-specifier-seq`*<sub>opt</sub> **`;`**
98+
>
99+
79100
## Implementing modules
80101

81-
You can create a module with a single interface file (*`.ixx`*) that exports names and includes implementations of all functions and types. You can also put the implementations in one or more separate implementation files, similar to how .h and .cpp files are used. The **`export`** keyword is used in the interface file only. An implementation file can **`import`** another module, but can't **`export`** any names. Implementation files may be named with any extension. An interface file and the backing set of implementation files are treated as a special variation of a translation unit called a *module unit*. A name that's declared in any implementation file is automatically visible in all other files within the same module unit.
102+
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 implementations in one or more separate module implementation files, similar to how *`.h`* and *`.cpp`* files are used.
103+
104+
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*, the public interface of the module that may also import and export the partition interfaces.
105+
106+
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:
107+
108+
- 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.
109+
110+
- A *module implementation unit* is a module unit that doesn't export a module name or module partition name. As the name implies, it's used to implement a module.
111+
112+
- 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.
113+
114+
- A *module partition interface unit* is a module interface unit that exports a module partition name.
115+
116+
- A *module partition implementation unit* is a module implementation unit that has a module partition name in its module declaration, but no `export` keyword.
82117

83-
For larger modules, you can split the module into multiple module units called *partitions*. Each partition consists of an interface file backed by one or more implementation files.
118+
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.
84119

85120
## Modules, namespaces, and argument-dependent lookup
86121

@@ -90,7 +125,7 @@ When it does argument-dependent lookup for overload resolutions in the importing
90125

91126
### Module partitions
92127

93-
A module can be componentized into *partitions*, each consisting of an interface file and zero or more implementation files. 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:
128+
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:
94129

95130
```cpp
96131
module Example:part1;
@@ -147,7 +182,7 @@ import std.filesystem;
147182

148183
### Imported header files
149184

150-
Some headers are sufficiently self-contained that they can be brought in using the **`import`** keyword. The main difference between an imported header and an imported module is that any preprocessor definitions in the header are visible in the importing program immediately after the `import` statement. However, preprocessor definitions in any files included by that header aren't visible.
185+
Some headers are sufficiently self-contained that they can be brought in using the **`import`** keyword. The main difference between an imported header and an imported module is that any preprocessor definitions in the header are visible in the importing program immediately after the `import` statement.
151186

152187
```cpp
153188
import <vector>;
@@ -156,4 +191,5 @@ import "myheader.h";
156191

157192
## See also
158193

159-
[`module`, `import`, `export`](import-export-module.md)
194+
[`module`, `import`, `export`](import-export-module.md)\
195+
[Named modules tutorial](tutorial-named-modules-cpp.md)

docs/ide/walkthrough-testing-a-project-cpp.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: "Learn more about: Walkthrough: Testing a Project (C++)"
33
title: "Walkthrough: Testing a Project (C++)"
4-
ms.date: "04/25/2019"
4+
ms.date: 03/15/2022
55
helpviewer_keywords: ["project testing [C++]", "testing projects", "projects [C++], testing"]
66
ms.assetid: 88cdd377-c5c8-4201-889d-32f5653ebead
77
---
@@ -19,7 +19,7 @@ In this walkthrough, you watch the value of a variable as the program runs and d
1919

2020
### To run a program in Debug mode
2121

22-
1. Open Games.cpp for editing.
22+
1. Open Game.cpp for editing.
2323

2424
1. Select this line of code:
2525

@@ -31,7 +31,7 @@ In this walkthrough, you watch the value of a variable as the program runs and d
3131

3232
1. On the menu bar, choose **Debug** > **Start Debugging**, or choose the **F5** key.
3333

34-
When the program reaches the line that has the breakpoint, execution stops temporarily, because your program is in Break mode. A yellow arrow to the left of a line of code indicates that it's the next line to be executed.
34+
Because your program is in Break mode, execution pauses when it reaches the breakpoint line. A yellow arrow to the left of a line of code indicates that it's the next line to be executed.
3535

3636
1. To examine the value of the `Cardgame::totalParticipants` variable, move the pointer over `Cardgame` and then move it over the expansion control at the left of the tooltip window. The variable name `totalParticipants` and its value of **12** are displayed.
3737

@@ -43,16 +43,16 @@ In this walkthrough, you watch the value of a variable as the program runs and d
4343

4444
1. Open the shortcut menu for the `return 0;` statement and then choose **Run to Cursor**. The yellow arrow to the left of the code points to the next statement to be executed.
4545

46-
1. The `Cardgame::totalParticipants` number should decrease when a `Cardgame` ends. At this point, `Cardgame::totalParticipants` should equal 0 because all `Cardgame` instances have been deleted, but the **Watch 1** window indicates that `Cardgame::totalparticipants` equals **18**. The difference indicates that there's a bug in the code, which you can detect and fix by completing the next walkthrough, [Walkthrough: Debugging a Project (C++)](../ide/walkthrough-debugging-a-project-cpp.md).
46+
1. The `Cardgame::totalParticipants` number should decrease when a `Cardgame` ends. At this point, `Cardgame::totalParticipants` should equal 0 because all `Cardgame` instances have been deleted, but the **Watch 1** window indicates that `Cardgame::totalparticipants` equals **18**. The difference indicates that there's a bug in the code. You can detect and fix it by completing the next walkthrough, [Walkthrough: Debugging a Project (C++)](../ide/walkthrough-debugging-a-project-cpp.md).
4747

4848
1. To stop the program, on the menu bar, choose **Debug** > **Stop Debugging**, or choose the **Shift**+**F5** keyboard shortcut.
4949

5050
## Next Steps
5151

52-
**Previous:** [Walkthrough: Building a Project (C++)](../ide/walkthrough-building-a-project-cpp.md)<br/>
52+
**Previous:** [Walkthrough: Building a Project (C++)](../ide/walkthrough-building-a-project-cpp.md)\
5353
**Next:** [Walkthrough: Debugging a Project (C++)](../ide/walkthrough-debugging-a-project-cpp.md)
5454

5555
## See also
5656

57-
[C++ Language Reference](../cpp/cpp-language-reference.md)<br/>
58-
[Projects and build systems](../build/projects-and-build-systems-cpp.md)<br/>
57+
[C++ Language Reference](../cpp/cpp-language-reference.md)\
58+
[Projects and build systems](../build/projects-and-build-systems-cpp.md)

docs/preprocessor/fp-contract.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: "Learn more about the fp_contract pragma directive in Microsoft C/C++"
33
title: "fp_contract pragma"
4-
ms.date: 08/10/2021
4+
ms.date: 03/22/2022
55
f1_keywords: ["vc-pragma.fp_contract", "fp_contract_CPP"]
66
helpviewer_keywords: ["pragma, fp_contract", "fp_contract pragma"]
77
no-loc: ["pragma"]
@@ -18,17 +18,15 @@ Determines whether floating-point contraction takes place. A floating-point cont
1818

1919
::: moniker range=">msvc-160"
2020

21-
By default, **`fp_contract`** is **`off`**, which tells the compiler to preserve individual floating-point instructions. Set **`fp_contract`** to **`on`** to use floating-point contraction instructions where possible. This behavior is new in Visual Studio 2022. In previous compiler versions **`fp_contract`** defaulted to **`on`**.
21+
When you use the default compiler options, **`fp_contract`** is **`off`**, which tells the compiler to preserve individual floating-point instructions. Set **`fp_contract`** to **`on`** to use floating-point contraction instructions where possible. This behavior is new in Visual Studio 2022 version 17.0. In previous compiler versions, **`fp_contract`** defaulted to **`on`**.
2222

2323
::: moniker-end
2424
::: moniker range="<=msvc-160"
2525

26-
By default, **`fp_contract`** is **`on`**. This tells the compiler to use floating-point contraction instructions where possible. Set **`fp_contract`** to **`off`** to preserve individual floating-point instructions.
26+
When you use the default compiler options, **`fp_contract`** is **`on`**. This setting tells the compiler to use floating-point contraction instructions where possible. Set **`fp_contract`** to **`off`** to preserve individual floating-point instructions. In Visual Studio 2022 version 17.0 and later, **`fp_contract`** defaults to **`off`**.
2727

2828
::: moniker-end
2929

30-
By default, **`fp_contract`** is **`off`**. This tells the compiler to preserve individual floating-point instructions. Set **`fp_contract`** to **`on`** to use floating-point contraction instructions where possible.
31-
3230
For more information on floating-point behavior, see [`/fp` (Specify floating-point behavior)](../build/reference/fp-specify-floating-point-behavior.md).
3331

3432
Other floating-point pragma directives include:
@@ -39,12 +37,11 @@ Other floating-point pragma directives include:
3937

4038
## Example
4139

42-
The code generated from this sample does not use a fused-multiply-add instruction even when it is available on the target processor. If you comment out `#pragma fp_contract (off)`, the generated code may use a fused-multiply-add instruction if it is available.
40+
The **`/fp:fast`** compiler option enables contractions by default, but the `#pragma fp_contract (off)` directive in this example turns them off. The code generated from this sample won't use a fused-multiply-add instruction even when it's available on the target processor. If you comment out `#pragma fp_contract (off)`, the generated code may use a fused-multiply-add instruction if it's available.
4341

4442
```cpp
4543
// pragma_directive_fp_contract.cpp
46-
// on x86 and x64 compile with: /O2 /fp:fast /arch:AVX2
47-
// other platforms compile with: /O2
44+
// On x86 and x64 compile with: /O2 /fp:fast /arch:AVX2
4845

4946
#include <stdio.h>
5047

0 commit comments

Comments
 (0)