Skip to content

Commit a5b952e

Browse files
authored
Doc new Zc conformance options (#4676)
1 parent b1db07f commit a5b952e

File tree

7 files changed

+207
-0
lines changed

7 files changed

+207
-0
lines changed

docs/build/reference/compiler-options-listed-alphabetically.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,19 @@ This table contains an alphabetical list of compiler options. For a list of comp
220220
| [`/Zc:externC[-]`](zc-externc.md) | Enforce Standard C++ rules for `extern "C"` functions (implied by **`/permissive-`**). |
221221
| [`/Zc:externConstexpr[-]`](zc-externconstexpr.md) | Enable external linkage for **`constexpr`** variables (off by default). |
222222
| [`/Zc:forScope[-]`](zc-forscope-force-conformance-in-for-loop-scope.md) | Enforce Standard C++ **`for`** scoping rules (on by default). |
223+
| [`/Zc:gotoScope`](zc-gotoscope.md) | Enforce Standard C++ **`goto`** rules around local variable initialization (implied by **`/permissive-`**). |
223224
| [`/Zc:hiddenFriend[-]`](zc-hiddenfriend.md) | Enforce Standard C++ hidden friend rules (implied by **`/permissive-`**) |
224225
| [`/Zc:implicitNoexcept[-]`](zc-implicitnoexcept-implicit-exception-specifiers.md) | Enable implicit **`noexcept`** on required functions (on by default). |
225226
| [`/Zc:inline[-]`](zc-inline-remove-unreferenced-comdat.md) | Remove unreferenced functions or data if they're COMDAT or have internal linkage only (off by default). |
226227
| [`/Zc:lambda[-]`](zc-lambda.md) | Enable new lambda processor for conformance-mode syntactic checks in generic lambdas. |
227228
| [`/Zc:noexceptTypes[-]`](zc-noexcepttypes.md) | Enforce C++17 **`noexcept`** rules (on by default in C++17 or later). |
229+
| [`/Zc:nrvo[-]`](zc-nrvo.md) | Enable optional copy and move elisions (on by default under **`/O2`**, **`/permissive-`**, or **`/std:c++20`** or later). |
228230
| [`/Zc:preprocessor[-]`](zc-preprocessor.md) | Use the new conforming preprocessor (off by default, except in C11/C17). |
229231
| [`/Zc:referenceBinding[-]`](zc-referencebinding-enforce-reference-binding-rules.md) | A UDT temporary won't bind to a non-const lvalue reference (off by default). |
230232
| [`/Zc:rvalueCast[-]`](zc-rvaluecast-enforce-type-conversion-rules.md) | Enforce Standard C++ explicit type conversion rules (off by default). |
231233
| [`/Zc:sizedDealloc[-]`](zc-sizeddealloc-enable-global-sized-dealloc-functions.md) | Enable C++14 global sized deallocation functions (on by default). |
232234
| [`/Zc:strictStrings[-]`](zc-strictstrings-disable-string-literal-type-conversion.md) | Disable string-literal to `char*` or `wchar_t*` conversion (off by default). |
235+
| [`/Zc:templateScope[-]`](zc-templatescope.md) | Enforce Standard C++ template parameter shadowing rules (off by default). |
233236
| [`/Zc:ternary[-]`](zc-ternary.md) | Enforce conditional operator rules on operand types (off by default). |
234237
| [`/Zc:threadSafeInit[-]`](zc-threadsafeinit-thread-safe-local-static-initialization.md) | Enable thread-safe local static initialization (on by default). |
235238
| [`/Zc:throwingNew[-]`](zc-throwingnew-assume-operator-new-throws.md) | Assume **`operator new`** throws on failure (off by default). |

docs/build/reference/compiler-options-listed-by-category.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,19 @@ This article contains a categorical list of compiler options. For an alphabetica
182182
| [`/Zc:externC[-]`](zc-externc.md) | Enforce Standard C++ rules for `extern "C"` functions (implied by **`/permissive-`**). |
183183
| [`/Zc:externConstexpr[-]`](zc-externconstexpr.md) | Enable external linkage for **`constexpr`** variables (off by default). |
184184
| [`/Zc:forScope[-]`](zc-forscope-force-conformance-in-for-loop-scope.md) | Enforce Standard C++ **`for`** scoping rules (on by default). |
185+
| [`/Zc:gotoScope`](zc-gotoscope.md) | Enforce Standard C++ **`goto`** rules around local variable initialization (implied by **`/permissive-`**). |
185186
| [`/Zc:hiddenFriend[-]`](zc-hiddenfriend.md) | Enforce Standard C++ hidden friend rules (implied by **`/permissive-`**) |
186187
| [`/Zc:implicitNoexcept[-]`](zc-implicitnoexcept-implicit-exception-specifiers.md) | Enable implicit **`noexcept`** on required functions (on by default). |
187188
| [`/Zc:inline[-]`](zc-inline-remove-unreferenced-comdat.md) | Remove unreferenced functions or data if they're COMDAT or have internal linkage only (off by default). |
188189
| [`/Zc:lambda[-]`](zc-lambda.md) | Enable new lambda processor for conformance-mode syntactic checks in generic lambdas. |
189190
| [`/Zc:noexceptTypes[-]`](zc-noexcepttypes.md) | Enforce C++17 **`noexcept`** rules (on by default in C++17 or later). |
191+
| [`/Zc:nrvo[-]`](zc-nrvo.md) | Enable optional copy and move elisions (on by default under **`/O2`**, **`/permissive-`**, or **`/std:c++20`** or later). |
190192
| [`/Zc:preprocessor[-]`](zc-preprocessor.md) | Use the new conforming preprocessor (off by default, except in C11/C17). |
191193
| [`/Zc:referenceBinding[-]`](zc-referencebinding-enforce-reference-binding-rules.md) | A UDT temporary won't bind to a non-const lvalue reference (off by default). |
192194
| [`/Zc:rvalueCast[-]`](zc-rvaluecast-enforce-type-conversion-rules.md) | Enforce Standard C++ explicit type conversion rules (off by default). |
193195
| [`/Zc:sizedDealloc[-]`](zc-sizeddealloc-enable-global-sized-dealloc-functions.md) | Enable C++14 global sized deallocation functions (on by default). |
194196
| [`/Zc:strictStrings[-]`](zc-strictstrings-disable-string-literal-type-conversion.md) | Disable string-literal to `char*` or `wchar_t*` conversion (off by default). |
197+
| [`/Zc:templateScope[-]`](zc-templatescope.md) | Enforce Standard C++ template parameter shadowing rules (off by default). |
195198
| [`/Zc:ternary[-]`](zc-ternary.md) | Enforce conditional operator rules on operand types (off by default). |
196199
| [`/Zc:threadSafeInit[-]`](zc-threadsafeinit-thread-safe-local-static-initialization.md) | Enable thread-safe local static initialization (on by default). |
197200
| [`/Zc:throwingNew[-]`](zc-throwingnew-assume-operator-new-throws.md) | Assume **`operator new`** throws on failure (off by default). |

docs/build/reference/zc-conformance.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,20 @@ Here are the **`/Zc`** compiler options:
3131
| [`/Zc:externC`](zc-externc.md) | Enforce Standard C++ rules for `extern "C"` functions (implied by **`/permissive-`**). |
3232
| [`/Zc:externConstexpr`](zc-externconstexpr.md) | Enable external linkage for **`constexpr`** variables (off by default). |
3333
| [`/Zc:forScope`](zc-forscope-force-conformance-in-for-loop-scope.md) | Enforce Standard C++ **`for`** scoping rules (on by default). |
34+
| [`/Zc:gotoScope`](zc-gotoscope.md) | Enforce Standard C++ **`goto`** rules around local variable initialization (implied by **`/permissive-`**). |
3435
| [`/Zc:hiddenFriend`](zc-hiddenfriend.md) | Enforce Standard C++ hidden friend rules (implied by **`/permissive-`**) |
3536
| [`/Zc:implicitNoexcept`](zc-implicitnoexcept-implicit-exception-specifiers.md) | Enable implicit **`noexcept`** on required functions (on by default). |
3637
| [`/Zc:inline`](zc-inline-remove-unreferenced-comdat.md) | Remove unreferenced functions or data if they're COMDAT or have internal linkage only (off by default). |
3738
| [`/Zc:lambda`](zc-lambda.md) | Enable new lambda processor for conformance-mode syntactic checks in generic lambdas. |
3839
| [`/Zc:noexceptTypes`](zc-noexcepttypes.md) | Enforce C++17 **`noexcept`** rules (on by default in C++17 or later). |
40+
| [`/Zc:nrvo[-]`](zc-nrvo.md) | Enable optional copy and move elisions (on by default under **`/O2`**, **`/permissive-`**, or **`/std:c++20`** or later). |
3941
| [`/Zc:preprocessor`](zc-preprocessor.md) | Use the new conforming preprocessor (off by default, except in C11/C17). |
4042
| [`/Zc:referenceBinding`](zc-referencebinding-enforce-reference-binding-rules.md) | A UDT temporary won't bind to a non-const lvalue reference (off by default). |
4143
| [`/Zc:rvalueCast`](zc-rvaluecast-enforce-type-conversion-rules.md) | Enforce Standard C++ explicit type conversion rules (off by default). |
4244
| [`/Zc:sizedDealloc`](zc-sizeddealloc-enable-global-sized-dealloc-functions.md) | Enable C++14 global sized deallocation functions (on by default). |
4345
| [`/Zc:strictStrings`](zc-strictstrings-disable-string-literal-type-conversion.md) | Disable string-literal to `char*` or `wchar_t*` conversion (off by default). |
4446
| [`/Zc:static_assert`](zc-static-assert.md) | strict handling of `static_assert` (implied by **`/permissive-`**). |
47+
| [`/Zc:templateScope[-]`](zc-templatescope.md) | Enforce Standard C++ template parameter shadowing rules (off by default). |
4548
| [`/Zc:ternary`](zc-ternary.md) | Enforce conditional operator rules on operand types (off by default). |
4649
| [`/Zc:threadSafeInit`](zc-threadsafeinit-thread-safe-local-static-initialization.md) | Enable thread-safe local static initialization (on by default). |
4750
| [`/Zc:throwingNew`](zc-throwingnew-assume-operator-new-throws.md) | Assume **`operator new`** throws on failure (off by default). |

docs/build/reference/zc-gotoscope.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
description: "Learn more about the /Zc:gotoScope (Enforce conformance in goto scope) compiler option."
3+
title: "/Zc:gotoScope (Enforce conformance in goto scope)"
4+
ms.date: 11/11/2022
5+
f1_keywords: ["/Zc:gotoScope"]
6+
helpviewer_keywords: ["-Zc:gotoScope compiler option (C++)", "/Zc:gotoScope compiler option (C++)"]
7+
---
8+
# `/Zc:gotoScope` (Enforce conformance in goto scope)
9+
10+
The **`/Zc:gotoScope`** compiler option enables checks for Standard C++ behavior around **`goto`** statements that jump over the initialization of local variables.
11+
12+
## Syntax
13+
14+
> **`/Zc:gotoScope`**\[**`-`**]
15+
16+
## Remarks
17+
18+
The **`/Zc:gotoScope`** compiler option enforces C++ Standard behavior around **`goto`** statements that jump over the initialization of one or more local variables. The compiler emits error [C2362](../../error-messages/compiler-errors-1/compiler-error-c2362.md) in all such cases when **`/Zc:gotoScope`** is specified. The **`/Zc:gotoScope-`** relaxes this check, but the compiler still emits an error if a **`goto`** skips initialization of a local variable that has a non-trivial destructor.
19+
20+
The intent of the **`/Zc:gotoScope-`** option is to help ease the migration of older code bases to more conformant code. You may use it to suppress certain errors until you've updated the non-conforming code.
21+
22+
The **`/Zc:gotoScope`** compiler option is new in Visual Studio 2022 version 17.4. The option is off by default. It's enabled automatically by the **`/permissive-`** option (or an option that implies **`/permissive-`**, such as **`/std:c++20`** or **`/std:c++latest`**). To enable the error check explicitly, add **`/Zc:gotoScope`** to the compiler command line. To explicitly disable the check, use the **`/Zc:gotoScope-`** option. The **`/Zc:gotoScope-`** must appear after the **`/permissive-`** option or any option that implies **`/permissive-`**.
23+
24+
### Example
25+
26+
This sample generates an error message when compiled using **`/Zc:gotoScope`**:
27+
28+
```cpp
29+
int g(int*);
30+
bool failed(int);
31+
32+
int f() {
33+
int v1;
34+
auto result = g(&v1);
35+
if (failed(result))
36+
goto OnError;
37+
int v2 = v1 + 2;
38+
return v2;
39+
OnError:
40+
return -1;
41+
}
42+
43+
/* Output:
44+
t.cpp(9): error C2362: initialization of 'v2' is skipped by 'goto OnError'
45+
*/
46+
```
47+
48+
If the code is compiled with **`/Zc:gotoScope-`**, the compiler doesn't emit the error.
49+
50+
Even when **`/Zc:gotoScope-`** is specified, the compiler still emits an error if the local variable has a non-trivial destructor. For example:
51+
52+
```cpp
53+
int g(int*);
54+
bool failed(int);
55+
56+
class S {
57+
public:
58+
S(int);
59+
~S();
60+
int mf() const;
61+
};
62+
63+
int f()
64+
{
65+
int v1;
66+
auto result = g(&v1);
67+
if (failed(result))
68+
goto OnError;
69+
S s(v1);
70+
return s.mf();
71+
72+
OnError:
73+
return -1;
74+
}
75+
76+
/* Output:
77+
t.cpp(17): error C2362: initialization of 's' is skipped by 'goto OnError'
78+
*/
79+
```
80+
81+
### To set this compiler option in Visual Studio
82+
83+
1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
84+
85+
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
86+
87+
1. In **Additional options**, add *`/Zc:gotoScope`* or *`/Zc:gotoScope-`*. Choose **OK** or **Apply** to save your changes.
88+
89+
## See also
90+
91+
[`/Zc` (Conformance)](zc-conformance.md)\
92+
[`/permissive-](./permissive-standards-conformance.md)\
93+
[`/std` (Specify language standard version)](std-specify-language-standard-version.md)

docs/build/reference/zc-nrvo.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
description: "Learn more about the /Zc:nrvo (Control optional NRVO) compiler option."
3+
title: "/Zc:nrvo (Control optional NRVO)"
4+
ms.date: 11/10/2022
5+
f1_keywords: ["/Zc:nrvo"]
6+
helpviewer_keywords: ["-Zc:nrvo compiler option (C++)", "/Zc:nrvo compiler option (C++)"]
7+
---
8+
# `/Zc:nrvo` (Control optional NRVO)
9+
10+
The **`/Zc:nrvo`** compiler option controls Standard C++ optional named return value optimization (NRVO) copy or move elision behavior.
11+
12+
## Syntax
13+
14+
> **`/Zc:nrvo`**\[**`-`**]
15+
16+
## Remarks
17+
18+
In Visual Studio 2022 version 17.4 and later, you can explicitly enable optional copy or move elision behavior by using the **`/Zc:nrvo`** compiler option. This option is off by default, but is set automatically when you compile using the **`/O2`** option, the **`/permissive-`** option, or **`/std:c++20`** or later. Under **`/Zc:nrvo`**, copy and move elision is performed wherever possible. Optional copy or move elision can also be explicitly disabled by using the **`/Zc:nrvo-`** option. These compiler options only control optional copy or move elision. Mandatory copy or move elision (specified by the C++ Standard) can't be disabled.
19+
20+
### Mandatory copy and move elision
21+
22+
The C++ standard requires copy or move elision when the returned value is initialized as part of the return statement. For example, it's required when a function returns an `ExampleType` returned by using `return ExampleType();`. The MSVC compiler always performs copy and move elision for **`return`** statements when it's required, even under **`/Zc:nrvo-`**.
23+
24+
### Optional copy and move elision
25+
26+
When a **`return`** statement contains an expression of non-primitive type, its execution copies the expression result into the return slot of the calling function. The compiler invokes the copy or move constructor of the returned type. Then, as the function is exited, destructors for function-local variables are called, which includes any variables named in the expression.
27+
28+
The C++ standard allows (but doesn't require) the compiler to optionally construct the returned object directly in the return slot of the calling function. This construction skips (or *elides*) the copy or move constructor executed as part of the **`return`** statement. Unlike most other optimizations, this transformation is allowed to have an observable effect on the program's output. Namely, the copy or move constructor and associated destructor are called one less time. The standard still requires that the named returned variable has a defined copy or move constructor, even if the compiler elides the constructor in all cases.
29+
30+
In versions before Visual Studio 2022 version 17.4, when optimizations are disabled (such as under **`/Od`** or in functions marked `#pragma optimize("", off)`) the compiler only performs mandatory copy and move elision. Under **`/O2`**, the older compilers perform optional copy or move elision on return of a named variable in an optimized function when all of these conditions are met: it has no loops or exception handling, it doesn't return multiple symbols with overlapping lifetimes, the type's copy or move constructor doesn't have default arguments.
31+
32+
Visual Studio 2022 version 17.4 increases the number of places where the compiler does optional copy or move elisions under **`/Zc:nrvo`**, whether enabled explicitly, or automatically by using the **`/O2`**, **`/permissive-`**, or **`/std:c++20`** or later options. Under **`/Zc:nrvo`**, the compiler performs optional copy or move elision on return of a named variable for any function when: it has no loops or exception handling (as before); it returns the variable from a loop; it has exception handling; the returned type's copy or move constructor has default arguments. Optional copy or move elisions are never done when **`/Zc:nrvo-`** is applied, or when the function returns multiple symbols with overlapping lifetimes, or for a throw of a named variable.
33+
34+
For more information and examples of mandatory and optional copy elision under **`/Zc:nrvo`**, see [Improving Copy and Move Elision](https://devblogs.microsoft.com/cppblog/improving-copy-and-move-elision) in the C++ Team Blog.
35+
36+
### To set this compiler option in Visual Studio
37+
38+
1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
39+
40+
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
41+
42+
1. In **Additional options**, add *`/Zc:nrvo`* or *`/Zc:nrvo-`*. Choose **OK** or **Apply** to save your changes.
43+
44+
## See also
45+
46+
[`/Zc` (Conformance)](zc-conformance.md)\
47+
[`/O2`](./o1-o2-minimize-size-maximize-speed.md)\
48+
[`/permissive-](./permissive-standards-conformance.md)\
49+
[`/std` (Specify language standard version)](std-specify-language-standard-version.md)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
description: "Learn more about the /Zc:templateScope (Check template parameter shadowing) compiler option."
3+
title: "/Zc:templateScope (Check template parameter shadowing)"
4+
ms.date: 11/11/2022
5+
f1_keywords: ["/Zc:templateScope"]
6+
helpviewer_keywords: ["-Zc:templateScope compiler option (C++)", "/Zc:templateScope compiler option (C++)"]
7+
---
8+
# `/Zc:templateScope` (Check template parameter shadowing)
9+
10+
The **`/Zc:templateScope`** compiler option enables checks for Standard C++ behavior around shadowing of template parameters.
11+
12+
## Syntax
13+
14+
> **`/Zc:templateScope`**\[**`-`**]
15+
16+
## Remarks
17+
18+
The C++ Standard doesn't allow the reuse of a template parameter's name (or *shadowing*) for another declaration within the scope of the template. The **`/Zc:templateScope`** compiler option enables an error check for such shadowing.
19+
20+
The **`/Zc:templateScope`** option is new in Visual Studio 2022 version 17.5 preview 1. The option is off by default even when the code is compiled using the **`/permissive-`** option (or an option that implies **`/permissive-`**, such as **`/std:c++20`** or **`/std:c++latest`**). To enable the error check, you must explicitly add **`/Zc:templateScope`** to the compiler command line. To explicitly disable the check, use the **`/Zc:templateScope-`** option.
21+
22+
### Example
23+
24+
Under **`/Zc:templateScope`**, this sample code produces an error:
25+
26+
```cpp
27+
template<typename T>
28+
void f(T&& t) {
29+
int T = 13;
30+
}
31+
32+
/* Output:
33+
t.cpp(3): error C7527: 'T': a template parameter name cannot be reused within its scope
34+
Compiling with '/Zc:templateScope' will inform the compiler to generate this diagnostic.
35+
*/
36+
```
37+
38+
### To set this compiler option in Visual Studio
39+
40+
1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
41+
42+
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
43+
44+
1. In **Additional options**, add *`/Zc:templateScope`* or *`/Zc:templateScope-`*. Choose **OK** or **Apply** to save your changes.
45+
46+
## See also
47+
48+
[`/Zc` (Conformance)](zc-conformance.md)\
49+
[`/permissive-](./permissive-standards-conformance.md)\
50+
[`/std` (Specify language standard version)](std-specify-language-standard-version.md)

0 commit comments

Comments
 (0)