You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/build/reference/zc-twophase.md
+24-24Lines changed: 24 additions & 24 deletions
Original file line number
Diff line number
Diff line change
@@ -1,29 +1,29 @@
1
1
---
2
2
title: "/Zc:twoPhase- (disable two-phase name lookup)"
3
3
description: "Explains how /Zc:twoPhase- disables two-phase name lookup when /permissive- is specified."
4
-
ms.date: "12/03/2019"
4
+
ms.date: 09/27/2022
5
5
f1_keywords: ["twoPhase", "/Zc:twoPhase"]
6
6
helpviewer_keywords: ["twoPhase", "disable two-phase name lookup", "/Zc:twoPhase"]
7
7
---
8
-
# /Zc:twoPhase- (disable two-phase name lookup)
8
+
# `/Zc:twoPhase-` (disable two-phase name lookup)
9
9
10
-
The **/Zc:twoPhase-** option, under **/permissive-**, tells the compiler to use the original, non-conforming Microsoft C++ compiler behavior to parse and instantiate class templates and function templates.
10
+
The **`/Zc:twoPhase-`** option, under **`/permissive-`**, tells the compiler to use the original, non-conforming Microsoft C++ compiler behavior to parse and instantiate class templates and function templates.
11
11
12
12
## Syntax
13
13
14
-
> **/Zc:twoPhase-**
14
+
> **`/Zc:twoPhase-`**
15
15
16
16
## Remarks
17
17
18
-
Visual Studio 2017 version 15.3 and later: Under [/permissive-](permissive-standards-conformance.md), the compiler uses two-phase name lookup for template name resolution. If you also specify **/Zc:twoPhase-**, the compiler reverts to its previous non-conforming class template and function template name resolution and substitution behavior. When **/permissive-** isn't specified, the non-conforming behavior is the default.
18
+
Visual Studio 2017 version 15.3 and later: Under [`/permissive-`](permissive-standards-conformance.md), the compiler uses two-phase name lookup for template name resolution. If you also specify **`/Zc:twoPhase-`**, the compiler reverts to its previous non-conforming class template and function template name resolution and substitution behavior. When **`/permissive-`** isn't specified, the non-conforming behavior is the default.
19
19
20
-
The Windows SDK header files in version 10.0.15063.0 (Creators Update or RS2) and earlier don't work in conformance mode. **/Zc:twoPhase-** is required to compile code for those SDK versions when you use **/permissive-**. Versions of the Windows SDK starting with version 10.0.15254.0 (Fall Creators Update or RS3) work correctly in conformance mode. They don't require the **/Zc:twoPhase-** option.
20
+
The Windows SDK header files in version 10.0.15063.0 (Creators Update or RS2) and earlier don't work in conformance mode. **`/Zc:twoPhase-`** is required to compile code for those SDK versions when you use **`/permissive-`**. Versions of the Windows SDK starting with version 10.0.15254.0 (Fall Creators Update or RS3) work correctly in conformance mode. They don't require the **`/Zc:twoPhase-`** option.
21
21
22
-
Use **/Zc:twoPhase-** if your code requires the old behavior to compile correctly. Strongly consider updating your code to conform to the standard.
22
+
Use **`/Zc:twoPhase-`** if your code requires the old behavior to compile correctly. Strongly consider updating your code to conform to the standard.
23
23
24
-
### Compiler behavior under /Zc:twoPhase-
24
+
### Compiler behavior under `/Zc:twoPhase-`
25
25
26
-
By default, or in Visual Studio 2017 version 15.3 and later when you specify both **/permissive-** and **/Zc:twoPhase-**, the compiler uses this behavior:
26
+
By default, or in Visual Studio 2017 version 15.3 and later when you specify both **`/permissive-`** and **`/Zc:twoPhase-`**, the compiler uses this behavior:
27
27
28
28
- It parses only the template declaration, the class head, and the base class list. The template body is captured as a token stream. No function bodies, initializers, default arguments, or noexcept arguments are parsed. The class template is pseudo-instantiated on a tentative type to validate that the declarations in the class template are correct. Consider this class template:
29
29
@@ -33,7 +33,7 @@ By default, or in Visual Studio 2017 version 15.3 and later when you specify bot
33
33
34
34
The template declaration, `template <typename T>`, the class head `class Derived`, and the base-class list `public Base<T>` are parsed, but the template body is captured as a token stream.
35
35
36
-
- When parsing a function template, the compiler parses only the function signature. The function body is never parsed. Instead, it's captured as a token stream.
36
+
- When it parses a function template, the compiler parses only the function signature. The function body is never parsed. Instead, it's captured as a token stream.
37
37
38
38
As a result, if the template body has syntax errors, but the template never gets instantiated, the compiler doesn't diagnose the errors.
39
39
@@ -65,7 +65,7 @@ int main()
65
65
}
66
66
```
67
67
68
-
Here's the output when you use the default mode, conformance mode, and conformance mode with **/Zc:twoPhase-** compiler options:
68
+
Here's the output when you use the default mode, conformance mode, and conformance mode with **`/Zc:twoPhase-`** compiler options:
When compiled in conformance mode under **/permissive-**, this program prints "`Standard two-phase`", because the second overload of `func` isn't visible when the compiler reaches the template. If you add **/Zc:twoPhase-**, the program prints "`Microsoft one-phase`". The output is the same as when you don't specify **/permissive-**.
84
+
When compiled in conformance mode under **`/permissive-`**, this program prints "`Standard two-phase`", because the second overload of `func` isn't visible when the compiler reaches the template. If you add **`/Zc:twoPhase-`**, the program prints "`Microsoft one-phase`". The output is the same as when you don't specify **`/permissive-`**.
85
85
86
-
*Dependent names* are names that depend on a template parameter. These names have lookup behavior that is also different under **/Zc:twoPhase-**. In conformance mode, dependent names aren't bound at the point of the template's definition. Instead, the compiler looks them up when it instantiates the template. For function calls with a dependent function name, the name gets bound to functions visible at the call site in the template definition. Additional overloads from argument-dependent lookup are added, both at the point of the template definition, and at the point of template instantiation.
86
+
*Dependent names* are names that depend on a template parameter. These names have lookup behavior that is also different under **`/Zc:twoPhase-`**. In conformance mode, dependent names aren't bound at the point of the template's definition. Instead, the compiler looks them up when it instantiates the template. For function calls with a dependent function name, the name gets bound to functions visible at the call site in the template definition. Other overloads from argument-dependent lookup are added, both at the point of the template definition, and at the point of template instantiation.
87
87
88
-
Two-phase lookup consists of two parts: The lookup for non-dependent names during template definition, and the lookup for dependent names during template instantiation. Under **/Zc:twoPhase-**, the compiler doesn't do argument-dependent lookup separately from unqualified lookup. That is, it doesn't do two-phase lookup, so the results of overload resolution may be different.
88
+
Two-phase lookup consists of two parts: The lookup for non-dependent names during template definition, and the lookup for dependent names during template instantiation. Under **`/Zc:twoPhase-`**, the compiler doesn't do argument-dependent lookup separately from unqualified lookup. That is, it doesn't do two-phase lookup, so the results of overload resolution may be different.
89
89
90
90
Here's another example:
91
91
@@ -118,28 +118,28 @@ int main() {
118
118
}
119
119
```
120
120
121
-
When compiled without **/permissive-**, this code prints:
121
+
When compiled without **`/permissive-`**, this code prints:
122
122
123
123
```Output
124
124
func(int)
125
125
NS::func(NS::S)
126
126
```
127
127
128
-
When compiled with **/permissive-**, but without **/Zc:twoPhase-**, this code prints:
128
+
When compiled with **`/permissive-`**, but without **`/Zc:twoPhase-`**, this code prints:
129
129
130
130
```Output
131
131
func(long)
132
132
NS::func(NS::S)
133
133
```
134
134
135
-
When compiled with both **/permissive-** and **/Zc:twoPhase-**, this code prints:
135
+
When compiled with both **`/permissive-`** and **`/Zc:twoPhase-`**, this code prints:
136
136
137
137
```Output
138
138
func(int)
139
139
NS::func(NS::S)
140
140
```
141
141
142
-
In conformance mode under **/permissive-**, the call `tfunc(1729)` resolves to the `void func(long)` overload. It doesn't resolve to the `void func(int)` overload, as under **/Zc:twoPhase-**. That's because the unqualified `func(int)` is declared after the definition of the template, and it isn't found through argument-dependent lookup. But `void func(S)` does participate in argument-dependent lookup, so it's added to the overload set for the call `tfunc(s)`, even though it's declared after the template function.
142
+
In conformance mode under **`/permissive-`**, the call `tfunc(1729)` resolves to the `void func(long)` overload. It doesn't resolve to the `void func(int)` overload, as under **`/Zc:twoPhase-`**. The reason is, the unqualified `func(int)` is declared after the definition of the template, and it isn't found through argument-dependent lookup. But `void func(S)` does participate in argument-dependent lookup, so it's added to the overload set for the call `tfunc(s)`, even though it's declared after the function template.
143
143
144
144
### Update your code for two-phase conformance
145
145
@@ -151,7 +151,7 @@ A conforming compiler parses `Foo` as a variable in the scope of `T`, meaning th
151
151
152
152
`T::template Foo<a || b>(c);`
153
153
154
-
In versions Visual Studio 2017 version 15.3 and later, when **/permissive-** and **/Zc:twoPhase-** are specified, the compiler allows this code without the **`template`** keyword. It interprets the code as a call to a function template with an argument of `a || b`, because it only parses templates in a limited fashion. The code above isn't parsed at all in the first phase. During the second phase, there's enough context to tell that `T::Foo` is a template rather than a variable, so the compiler doesn't enforce use of the keyword.
154
+
In versions Visual Studio 2017 version 15.3 and later, when **`/permissive-`** and **`/Zc:twoPhase-`** are specified, the compiler allows this code without the **`template`** keyword. It interprets the code as a call to a function template with an argument of `a || b`, because it only parses templates in a limited fashion. The code above isn't parsed at all in the first phase. During the second phase, there's enough context to tell that `T::Foo` is a template rather than a variable, so the compiler doesn't enforce use of the keyword.
155
155
156
156
This behavior can also be seen by eliminating the keyword **`typename`** before names in function template bodies, initializers, default arguments, and noexcept arguments. For example:
If you don't use the keyword **`typename`** in the function body, this code compiles under **/permissive- /Zc:twoPhase-**, but not under **/permissive-** alone. The **`typename`** keyword is required to indicate that the `TYPE` is dependent. Because the body isn't parsed under **/Zc:twoPhase-**, the compiler does't require the keyword. In **/permissive-** conformance mode, code without the **`typename`** keyword generates errors. To migrate your code to conformance in Visual Studio 2017 version 15.3 and beyond, insert the **`typename`** keyword where it's missing.
166
+
If you don't use the keyword **`typename`** in the function body, this code compiles under **`/permissive- /Zc:twoPhase-`**, but not under **`/permissive-`** alone. The **`typename`** keyword is required to indicate that the `TYPE` is dependent. Because the body isn't parsed under **`/Zc:twoPhase-`**, the compiler does't require the keyword. In **`/permissive-`** conformance mode, code without the **`typename`** keyword generates errors. To migrate your code to conformance in Visual Studio 2017 version 15.3 and beyond, insert the **`typename`** keyword where it's missing.
Under **/permissive- /Zc:twoPhase-** and in older compilers, the compiler only requires the **`template`** keyword on line 2. In conformance mode, the compiler now also requires the **`template`** keyword on line 4 to indicate that `T::X<T>` is a template. Look for code that is missing this keyword, and supply it to make your code conform to the standard.
178
+
Under **`/permissive- /Zc:twoPhase-`** and in older compilers, the compiler only requires the **`template`** keyword on line 2. In conformance mode, the compiler now also requires the **`template`** keyword on line 4 to indicate that `T::X<T>` is a template. Look for code that is missing this keyword, and supply it to make your code conform to the standard.
179
179
180
-
For more information about conformance issues, see [C++ conformance improvements in Visual Studio](../../overview/cpp-conformance-improvements.md) and [Nonstandard Behavior](../../cpp/nonstandard-behavior.md).
180
+
For more information about conformance issues, see [C++ conformance improvements in Visual Studio](../../overview/cpp-conformance-improvements.md) and [Nonstandard behavior](../../cpp/nonstandard-behavior.md).
181
181
182
182
### To set this compiler option in the Visual Studio development environment
183
183
184
184
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).
0 commit comments