Skip to content

Commit c8d132f

Browse files
author
Colin Robertson
authored
Fixes for various GitHub issues. (#4066)
* Fixes for various GitHub issues. * Fix grammar, remove obsolete notes
1 parent 02fa017 commit c8d132f

10 files changed

+91
-87
lines changed

docs/build/reference/experimental-module.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
22
title: "/experimental:module (Enable module support)"
33
description: "Use the /experimental:module compiler option to enable experimental compiler support for named modules."
4-
ms.date: "04/13/2021"
4+
ms.date: 01/27/2022
55
f1_keywords: ["module", "/experimental:module"]
66
helpviewer_keywords: ["module", "/experimental:module", "Enable module support"]
77
---
88
# `/experimental:module` (Enable module support)
99

10-
Enables experimental compiler support for C++ Standard modules. This option is obsolete in Visual Studio version 16.11 and later.
10+
Enables experimental compiler support for C++ Standard modules. This option is obsolete for C++20 standard modules in Visual Studio version 16.11 and later. It's still required (along with [`/std:c++latest`](std-specify-language-standard-version.md)) for the experimental Standard library modules.
1111

1212
## Syntax
1313

docs/build/reference/makefile-preprocessing.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Expressions can use the following operators. The operators of equal precedence a
9696
| **`~`** | Unary one's complement. |
9797
| **`-`** | Unary negation. |
9898
| | |
99-
| **`*`*** | Multiplication. |
99+
| **`*`** | Multiplication. |
100100
| **`/`** | Division. |
101101
| **`%`** | Modulus (remainder). |
102102
| | |
@@ -120,7 +120,7 @@ Expressions can use the following operators. The operators of equal precedence a
120120
| | |
121121
| **`&&`** | Logical AND. |
122122
| | |
123-
| **` | | `** | Logical OR. |
123+
| **` || `** | Logical OR. |
124124

125125
> [!NOTE]
126126
> The bitwise XOR operator (**`^`**) is the same as the escape character, and must be escaped (as **`^^`**) when it's used in an expression.

docs/build/walkthrough-compile-a-c-program-on-the-command-line.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ If you've installed Microsoft Visual C++ Build Tools 2015 on Windows 10 or later
6161

6262
If you're using a different version of Windows, look in your Start menu or Start page for a Visual Studio tools folder that contains a developer command prompt shortcut. You can also use the Windows search function to search for "developer command prompt" and choose one that matches your installed version of Visual Studio. Use the shortcut to open the command prompt window.
6363

64-
Next, verify that the Visual C++ developer command prompt is set up correctly. In the command prompt window, enter `cl` and verify that the output looks something like this:
64+
Next, verify that the Visual C++ developer command prompt is set up correctly. In the command prompt window, enter `cl` (or `CL`, case doesn't matter for the compiler name, but it does matter for compiler options). The output should look something like this:
6565

6666
```Output
6767
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise>cl

docs/code-quality/best-practices-and-examples-sal.md

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
---
2-
description: "Learn more about: Best Practices and Examples (SAL)"
3-
title: Best Practices and Examples (SAL)
4-
ms.date: 11/04/2016
2+
description: "Learn more about: Best practices and examples (SAL)"
3+
title: Best practices and examples (SAL)
4+
ms.date: 01/27/2022
55
ms.topic: "conceptual"
66
---
7-
# Best Practices and Examples (SAL)
7+
# Best practices and examples (SAL)
88

99
Here are some ways to get the most out of the Source Code Annotation Language (SAL) and avoid some common problems.
1010

11-
## \_In\_
11+
## `_In_`
1212

13-
If the function is supposed to write to the element, use `_Inout_` instead of `_In_`. This is particularly relevant in cases of automated conversion from older macros to SAL. Prior to SAL, many programmers used macros as comments—macros that were named `IN`, `OUT`, `IN_OUT`, or variants of these names. Although we recommend that you convert these macros to SAL, we also urge you to be careful when you convert them because the code might have changed since the original prototype was written and the old macro might no longer reflect what the code does. Be especially careful about the `OPTIONAL` comment macro because it is frequently placed incorrectly—for example, on the wrong side of a comma.
13+
If the function is supposed to write to the element, use `_Inout_` instead of `_In_`. This is particularly relevant in cases of automated conversion from older macros to SAL. Prior to SAL, many programmers used macros as comments—macros that were named `IN`, `OUT`, `IN_OUT`, or variants of these names. Although we recommend that you convert these macros to SAL, we also urge you to be careful when you convert them because the code might have changed since the original prototype was written and the old macro might no longer reflect what the code does. Be especially careful about the `OPTIONAL` comment macro because it's frequently placed incorrectly—for example, on the wrong side of a comma.
1414

1515
```cpp
16+
#include <sal.h>
1617

1718
// Incorrect
1819
void Func1(_In_ int *p1)
@@ -33,11 +34,12 @@ void Func2(_Inout_ PCHAR p1)
3334
}
3435
```
3536
36-
## \_opt\_
37+
## `_opt_`
3738
38-
If the caller is not allowed to pass in a null pointer, use `_In_` or `_Out_` instead of `_In_opt_` or `_Out_opt_`. This applies even to a function that checks its parameters and returns an error if it is NULL when it should not be. Although having a function check its parameter for unexpected NULL and return gracefully is a good defensive coding practice, it does not mean that the parameter annotation can be of an optional type (`_*Xxx*_opt_`).
39+
If the caller isn't allowed to pass in a null pointer, use `_In_` or `_Out_` instead of `_In_opt_` or `_Out_opt_`. This applies even to a function that checks its parameters and returns an error if it is `NULL` when it shouldn't be. Although having a function check its parameter for unexpected `NULL` and return gracefully is a good defensive coding practice, it doesn't mean that the parameter annotation can be of an optional type (`_*Xxx*_opt_`).
3940
4041
```cpp
42+
#include <sal.h>
4143
4244
// Incorrect
4345
void Func1(_Out_opt_ int *p1)
@@ -52,27 +54,29 @@ void Func2(_Out_ int *p1)
5254
}
5355
```
5456

55-
## \_Pre\_defensive\_ and \_Post\_defensive\_
57+
## `_Pre_defensive_` and `_Post_defensive_`
5658

57-
If a function appears at a trust boundary, we recommend that you use the `_Pre_defensive_` annotation. The "defensive" modifier modifies certain annotations to indicate that, at the point of call, the interface should be checked strictly, but in the implementation body it should assume that incorrect parameters might be passed. In that case, `_In_ _Pre_defensive_` is preferred at a trust boundary to indicate that although a caller will get an error if it attempts to pass NULL, the function body will be analyzed as if the parameter might be NULL, and any attempts to de-reference the pointer without first checking it for NULL will be flagged. A `_Post_defensive_` annotation is also available, for use in callbacks where the trusted party is assumed to be the caller and the untrusted code is the called code.
59+
If a function appears at a trust boundary, we recommend that you use the `_Pre_defensive_` annotation. The "defensive" modifier modifies certain annotations to indicate that, at the point of call, the interface should be checked strictly, but in the implementation body it should assume that incorrect parameters might be passed. In that case, `_In_ _Pre_defensive_` is preferred at a trust boundary to indicate that although a caller will get an error if it attempts to pass `NULL`, the function body will be analyzed as if the parameter might be `NULL`, and any attempts to de-reference the pointer without first checking it for `NULL` will be flagged. A `_Post_defensive_` annotation is also available, for use in callbacks where the trusted party is assumed to be the caller and the untrusted code is the called code.
5860

59-
## \_Out\_writes\_
61+
## `_Out_writes_`
6062

6163
The following example demonstrates a common misuse of `_Out_writes_`.
6264

6365
```cpp
66+
#include <sal.h>
6467

6568
// Incorrect
6669
void Func1(_Out_writes_(size) CHAR *pb,
6770
DWORD size
6871
);
6972
```
7073

71-
The annotation `_Out_writes_` signifies that you have a buffer. It has `cb` bytes allocated, with the first byte initialized on exit. This annotation is not strictly wrong and it is helpful to express the allocated size. However, it does not tell how many elements are initialized by the function.
74+
The annotation `_Out_writes_` signifies that you have a buffer. It has `cb` bytes allocated, with the first byte initialized on exit. This annotation isn't strictly wrong and it's helpful to express the allocated size. However, it doesn't tell how many elements are initialized by the function.
7275

7376
The next example shows three correct ways to fully specify the exact size of the initialized portion of the buffer.
7477

7578
```cpp
79+
#include <sal.h>
7680

7781
// Correct
7882
void Func1(_Out_writes_to_(size, *pCount) CHAR *pb,
@@ -89,11 +93,12 @@ void Func3(_Out_writes_(size) PSTR pb,
8993
);
9094
```
9195

92-
## \_Out\_ PSTR
96+
## `_Out_ PSTR`
9397

94-
The use of `_Out_ PSTR` is almost always wrong. This is interpreted as having an output parameter that points to a character buffer and it is NULL-terminated.
98+
The use of `_Out_ PSTR` is almost always wrong. This combination is interpreted as having an output parameter that points to a character buffer and the buffer is null-terminated.
9599

96100
```cpp
101+
#include <sal.h>
97102

98103
// Incorrect
99104
void Func1(_Out_ PSTR pFileName, size_t n);
@@ -102,13 +107,14 @@ void Func1(_Out_ PSTR pFileName, size_t n);
102107
void Func2(_Out_writes_(n) PSTR wszFileName, size_t n);
103108
```
104109
105-
An annotation like `_In_ PCSTR` is common and useful. It points to an input string that has NULL termination because the precondition of `_In_` allows the recognition of a NULL-terminated string.
110+
An annotation like `_In_ PCSTR` is common and useful. It points to an input string that has null termination because the precondition of `_In_` allows the recognition of a null-terminated string.
106111
107-
## \_In\_ WCHAR* p
112+
## `_In_ WCHAR* p`
108113
109-
`_In_ WCHAR* p` says that there is an input pointer `p` that points to one character. However, in most cases, this is probably not the specification that is intended. Instead, what is probably intended is the specification of a NULL-terminated array; to do that, use `_In_ PWSTR`.
114+
`_In_ WCHAR* p` says that there's an input pointer `p` that points to one character. However, in most cases, this is probably not the specification that is intended. Instead, what is probably intended is the specification of a null-terminated array; to do that, use `_In_ PWSTR`.
110115
111116
```cpp
117+
#include <sal.h>
112118
113119
// Incorrect
114120
void Func1(_In_ WCHAR* wszFileName);
@@ -117,9 +123,11 @@ void Func1(_In_ WCHAR* wszFileName);
117123
void Func2(_In_ PWSTR wszFileName);
118124
```
119125

120-
Missing the proper specification of NULL termination is common. Use the appropriate `STR` version to replace the type, as shown in the following example.
126+
Missing the proper specification of null termination is common. Use the appropriate `STR` version to replace the type, as shown in the following example.
121127

122128
```cpp
129+
#include <sal.h>
130+
#include <string.h>
123131

124132
// Incorrect
125133
BOOL StrEquals1(_In_ PCHAR p1, _In_ PCHAR p2)
@@ -134,11 +142,12 @@ BOOL StrEquals2(_In_ PSTR p1, _In_ PSTR p2)
134142
}
135143
```
136144
137-
## \_Out\_range\_
145+
## `_Out_range_`
138146
139-
If the parameter is a pointer and you want to express the range of the value of the element that is pointed to by the pointer, use `_Deref_out_range_` instead of `_Out_range_`. In the following example, the range of *pcbFilled is expressed, not pcbFilled.
147+
If the parameter is a pointer and you want to express the range of the value of the element that's pointed to by the pointer, use `_Deref_out_range_` instead of `_Out_range_`. In the following example, the range of *pcbFilled is expressed, not pcbFilled.
140148
141149
```cpp
150+
#include <sal.h>
142151
143152
// Incorrect
144153
void Func1(
@@ -155,13 +164,14 @@ void Func2(
155164
);
156165
```
157166

158-
`_Deref_out_range_(0, cbSize)` is not strictly required for some tools because it can be inferred from `_Out_writes_to_(cbSize,*pcbFilled)`, but it is shown here for completeness.
167+
`_Deref_out_range_(0, cbSize)` isn't strictly required for some tools because it can be inferred from `_Out_writes_to_(cbSize,*pcbFilled)`, but it's shown here for completeness.
159168

160-
## Wrong context in \_When\_
169+
## Wrong context in `_When_`
161170

162171
Another common mistake is to use post-state evaluation for preconditions. In the following example, `_Requires_lock_held_` is a precondition.
163172

164173
```cpp
174+
#include <sal.h>
165175

166176
// Incorrect
167177
_When_(return == 0, _Requires_lock_held_(p->cs))
@@ -172,11 +182,11 @@ _When_(flag == 0, _Requires_lock_held_(p->cs))
172182
int Func2(_In_ MyData *p, int flag);
173183
```
174184
175-
The expression `result` refers to a post-state value that is not available in pre-state.
185+
The expression `return` refers to a post-state value that isn't available in pre-state.
176186
177-
## TRUE in \_Success\_
187+
## `TRUE` in `_Success_`
178188
179-
If the function succeeds when the return value is nonzero, use `return != 0` as the success condition instead of `return == TRUE`. Nonzero does not necessarily mean equivalence to the actual value that the compiler provides for `TRUE`. The parameter to `_Success_` is an expression, and the following expressions are evaluated as equivalent: `return != 0`, `return != false`, `return != FALSE`, and `return` with no parameters or comparisons.
189+
If the function succeeds when the return value is nonzero, use `return != 0` as the success condition instead of `return == TRUE`. Nonzero doesn't necessarily mean equivalence to the actual value that the compiler provides for `TRUE`. The parameter to `_Success_` is an expression, and the following expressions are evaluated as equivalent: `return != 0`, `return != false`, `return != FALSE`, and `return` with no parameters or comparisons.
180190
181191
```cpp
182192
// Incorrect
@@ -194,9 +204,10 @@ BOOL WINAPI TryEnterCriticalSection(
194204

195205
## Reference variable
196206

197-
For a reference variable, the previous version of SAL used the implied pointer as the annotation target and required the addition of a `__deref` to annotations that attached to a reference variable. This version uses the object itself and does not require the additional `_Deref_`.
207+
For a reference variable, the previous version of SAL used the implied pointer as the annotation target and required the addition of a `__deref` to annotations that attached to a reference variable. This version uses the object itself and doesn't require the additional `_Deref_`.
198208

199209
```cpp
210+
#include <sal.h>
200211

201212
// Incorrect
202213
void Func1(
@@ -216,6 +227,7 @@ void Func2(
216227
The following example shows a common problem in return value annotations.
217228

218229
```cpp
230+
#include <sal.h>
219231

220232
// Incorrect
221233
_Out_opt_ void *MightReturnNullPtr1();
@@ -224,15 +236,15 @@ _Out_opt_ void *MightReturnNullPtr1();
224236
_Ret_maybenull_ void *MightReturnNullPtr2();
225237
```
226238

227-
In this example, `_Out_opt_` says that the pointer might be NULL as part of the precondition. However, preconditions cannot be applied to the return value. In this case, the correct annotation is `_Ret_maybenull_`.
239+
In this example, `_Out_opt_` says that the pointer might be `NULL` as part of the precondition. However, preconditions can't be applied to the return value. In this case, the correct annotation is `_Ret_maybenull_`.
228240

229241
## See also
230242

231-
[Using SAL Annotations to Reduce C/C++ Code Defects](../code-quality/using-sal-annotations-to-reduce-c-cpp-code-defects.md)
232-
[Understanding SAL](../code-quality/understanding-sal.md)
233-
[Annotating Function Parameters and Return Values](../code-quality/annotating-function-parameters-and-return-values.md)
234-
[Annotating Function Behavior](../code-quality/annotating-function-behavior.md)
235-
[Annotating Structs and Classes](../code-quality/annotating-structs-and-classes.md)
236-
[Annotating Locking Behavior](../code-quality/annotating-locking-behavior.md)
237-
[Specifying When and Where an Annotation Applies](../code-quality/specifying-when-and-where-an-annotation-applies.md)
238-
[Intrinsic Functions](../code-quality/intrinsic-functions.md)
243+
[Using SAL annotations to reduce C/C++ code defects](../code-quality/using-sal-annotations-to-reduce-c-cpp-code-defects.md)\
244+
[Understanding SAL](../code-quality/understanding-sal.md)\
245+
[Annotating function parameters and return values](../code-quality/annotating-function-parameters-and-return-values.md)\
246+
[Annotating function behavior](../code-quality/annotating-function-behavior.md)\
247+
[Annotating structs and classes](../code-quality/annotating-structs-and-classes.md)\
248+
[Annotating locking behavior](../code-quality/annotating-locking-behavior.md)\
249+
[Specifying when and where an annotation applies](../code-quality/specifying-when-and-where-an-annotation-applies.md)\
250+
[Intrinsic functions](../code-quality/intrinsic-functions.md)

docs/code-quality/c26462.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ description: CppCoreCheck rule C26462 that enforces C++ Core Guidelines Con.4
1010

1111
The value pointed to by '%variable%' is assigned only once, mark it as a pointer to `const` (con.4).
1212

13-
Pointers to variables whose values remain unchanged should be marked as const.
13+
Pointers to variables whose values remain unchanged should be marked as `const`.
1414

1515
## See also
1616

docs/cpp/import-export-module.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ In an interface file, use the **`export`** modifier on names that are intended t
3232

3333
export module ModuleA;
3434

35-
namespace Bar
35+
namespace ModuleA_NS
3636
{
3737
export int f();
3838
export double d();
@@ -48,17 +48,17 @@ Non-exported names are not visible to code that imports the module:
4848
import ModuleA;
4949

5050
int main() {
51-
Bar::f(); // OK
52-
Bar::d(); // OK
53-
Bar::internal_f(); // Ill-formed: error C2065: 'internal_f': undeclared identifier
51+
ModuleA_NS::f(); // OK
52+
ModuleA_NS::d(); // OK
53+
ModuleA_NS::internal_f(); // Ill-formed: error C2065: 'internal_f': undeclared identifier
5454
}
5555
```
5656

5757
The **`export`** keyword may not appear in a module implementation file. When **`export`** is applied to a namespace name, all names in the namespace are exported.
5858

5959
## import
6060

61-
Use an **import** declaration to make a module's names visible in your program. The import declaration must appear after the module declaration and after any #include directives, but before any declarations in the file.
61+
Use an **`import`** declaration to make a module's names visible in your program. The `import` declaration must appear after the `module` declaration and after any `#include` directives, but before any declarations in the file.
6262

6363
```cpp
6464
module ModuleA;
@@ -100,7 +100,7 @@ int i; module ;
100100

101101
**Microsoft Specific**
102102

103-
In Microsoft C++, the tokens **import** and **module** are always identifiers and never keywords when they are used as arguments to a macro.
103+
In Microsoft C++, the tokens **`import`** and **`module`** are always identifiers and never keywords when they are used as arguments to a macro.
104104

105105
### Example
106106

docs/cpp/lambda-expressions-in-cpp.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,7 @@ You can use a capture-default mode to indicate how to capture any outside variab
6161
[&total, factor]
6262
[factor, &total]
6363
[&, factor]
64-
[factor, &]
6564
[=, &total]
66-
[&total, =]
6765
```
6866

6967
Only variables that are mentioned in the lambda body are captured when a capture-default is used.

0 commit comments

Comments
 (0)