Skip to content

Commit c9d2247

Browse files
author
Colin Robertson
committed
Fixes per comments
1 parent d9b1dde commit c9d2247

File tree

2 files changed

+50
-40
lines changed

2 files changed

+50
-40
lines changed

docs/build/reference/permissive-standards-conformance.md

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ By default, the **/permissive-** option is not set. When the option is set, the
5353

5454
The **/permissive-** option sets the [/Zc:strictStrings](../../build/reference/zc-conformance.md) and [/Zc:rvalueCast](../../build/reference/zc-conformance.md) options to conforming behavior. They default to non-conforming behavior. You can pass specific **/Zc** options after **/permissive-** on the command line to override this behavior.
5555

56-
In versions of the compiler beginning in Visual Studio 2017 Update 3, the **/permissive-** option sets the [/Zc:ternary]() option. The compiler also implements more of the requirements for two-phase name look-up. When the **/permissive-** option is set, the compiler parses function and class template definitions, identifying dependent and non-dependent names used in the templates. In this release, only name dependency analysis is performed.
56+
In versions of the compiler beginning in Visual Studio 2017 Update Version 15.3, the **/permissive-** option sets the [/Zc:ternary]() option. The compiler also implements more of the requirements for two-phase name look-up. When the **/permissive-** option is set, the compiler parses function and class template definitions, identifying dependent and non-dependent names used in the templates. In this release, only name dependency analysis is performed.
5757

5858
Environment-specific extensions and language areas that the standard leaves up to the implementation are not affected by **/permissive-**. For example, the Microsoft-specific `__declspec`, calling convention and structured exception handling keywords, and compiler-specific pragma directives or attributes are not flagged by the compiler in **/permissive-** mode.
5959

60-
The **/permissive-** option uses the conformance support in the current compiler version to determine which language constructs are non-conforming. The option does not determine if your code conforms to a specific version of the C++ standard. To enable all implemented compiler support for the latest draft standard, use the [/std:latest](../../build/reference/std-specify-language-standard-version.md) option. To restrict the compiler support to more closely match the C++14 standard, use the [/std:c++14](../../build/reference/std-specify-language-standard-version.md) option, which is the default.
60+
The **/permissive-** option uses the conformance support in the current compiler version to determine which language constructs are non-conforming. The option does not determine if your code conforms to a specific version of the C++ standard. To enable all implemented compiler support for the latest draft standard, use the [/std:latest](../../build/reference/std-specify-language-standard-version.md) option. To restrict the compiler support to the currently implemented C++17 standard, use the [/std:c++17](../../build/reference/std-specify-language-standard-version.md) option. To restrict the compiler support to more closely match the C++14 standard, use the [/std:c++14](../../build/reference/std-specify-language-standard-version.md) option, which is the default.
6161

62-
Not all C++11, C++14, or draft C++17 standards-conforming code is supported by the Visual C++ compiler in Visual Studio 2017. The **/permissive-** option may not detect issues regarding two-phase name lookup, binding a non-const reference to a temporary, treating copy init as direct init, allowing multiple user-defined conversions in initialization, or alternative tokens for logical operators, and other non-supported conformance areas. For more information about conformance issues in Visual C++, see [Nonstandard Behavior](../../cpp/nonstandard-behavior.md).
62+
Not all C++11, C++14, or C++17 standards-conforming code is supported by the Visual C++ compiler in Visual Studio 2017. The **/permissive-** option may not detect issues regarding some aspects of two-phase name lookup, binding a non-const reference to a temporary, treating copy init as direct init, allowing multiple user-defined conversions in initialization, or alternative tokens for logical operators, and other non-supported conformance areas. For more information about conformance issues in Visual C++, see [Nonstandard Behavior](../../cpp/nonstandard-behavior.md).
6363

6464
### How to fix your code
6565
Here are some examples of code that is detected as non-conforming when you use **/permissive-**, along with suggested ways to fix the issues.
@@ -238,7 +238,7 @@ class ATL_NO_VTABLE CFooImpl : public ICustom,
238238
239239
#### Ambiguous conditional operator arguments
240240
241-
In versions of the compiler before Visual Studio 2017 Update 3, the compiler accepted arguments to the conditional operator (or ternary operator) `?:` that are considered ambiguous by the C++17 standard. In **/permissive-** mode, the compiler now issues one or more diagnostics in cases that compiled without diagnostics in earlier versions.
241+
In versions of the compiler before Visual Studio 2017 Update Version 15.3, the compiler accepted arguments to the conditional operator (or ternary operator) `?:` that are considered ambiguous by the Standard. In **/permissive-** mode, the compiler now issues one or more diagnostics in cases that compiled without diagnostics in earlier versions.
242242
243243
Commmon errors that may result from this change include:
244244
@@ -264,13 +264,13 @@ extern bool cond;
264264
265265
A a(42);
266266
// Accepted when /Zc:ternary or /permissive- is not used:
267-
auto x = cond ? 7 : a; // A: permissive prefers A(7) over (int)a
267+
auto x = cond ? 7 : a; // A: permissive behavior prefers A(7) over (int)a
268268
// Accepted always:
269269
auto y = cond ? 7 : int(a);
270270
auto z = cond ? A(7) : a;
271271
```
272272

273-
There is an important exception to this common pattern when T represents one of the null-terminated string types (for example, `const char *`, `const char16_t *`, and so on) and the actual argument to `?:` is a string literal of corresponding type. C++17 has changed semantics from C++14. As a result, the code in example 2 is accepted under /std:c++14 and rejected under /std:c++17 when **/Zc:ternary** or **/permissive-** is used.
273+
There is an important exception to this common pattern when T represents one of the null-terminated string types (for example, `const char *`, `const char16_t *`, and so on) and the actual argument to `?:` is a string literal of corresponding type. C++17 has changed semantics from C++14. As a result, the code in example 2 is accepted under **/std:c++14** and rejected under **/std:c++17** when **/Zc:ternary** or **/permissive-** is used.
274274

275275
```cpp
276276
// Example 2: exception from the above
@@ -279,11 +279,15 @@ struct MyString
279279
MyString(const char* s = "") noexcept; // from char*
280280
operator const char* () const noexcept; // to char*
281281
};
282+
283+
extern bool cond;
282284

283285
MyString s;
284-
// Accepted when /Zc:ternary or /permissive- is not used:
285-
auto x = cond ? "A" : s; // MyString: permissive prefers MyString("A") over (const char*)s
286-
// Accepted always:
286+
// Using /std:c++14, /permissive- or /Zc:ternary behavior
287+
// is to prefer MyString("A") over (const char*)s
288+
// but under /std:c++17 this line causes error C2445:
289+
auto x = cond ? "A" : s;
290+
// You can use a static_cast to resolve the ambiguity:
287291
auto y = cond ? "A" : static_cast<const char*>(s);
288292
```
289293
@@ -293,48 +297,50 @@ Another case where you may see errors is in conditional optators with one argume
293297
// Example 3: void arguments
294298
void myassert(const char* text, const char* file, int line);
295299
// Accepted when /Zc:ternary or /permissive- is not used:
296-
#define ASSERT(ex) (void)((ex) ? 0 : myassert(#ex, __FILE__, __LINE__))
300+
#define ASSERT_A(ex) (void)((ex) ? 1 : myassert(#ex, __FILE__, __LINE__))
297301
// Accepted always:
298-
#define ASSERT(ex) (void)((ex) ? void() : myassert(#ex, __FILE__, __LINE__))
302+
#define ASSERT_B(ex) (void)((ex) ? void() : myassert(#ex, __FILE__, __LINE__))
299303
```
300304

301-
You may also see errors in template metaprogramming, where conditional operator result types may change under **/Zc:ternary** and **/permissive-**. One way to resolve this issue is to use `std::remove_reference` on the resulting type.
305+
You may also see errors in template metaprogramming, where conditional operator result types may change under **/Zc:ternary** and **/permissive-**. One way to resolve this issue is to use [std::remove_reference](../../standard-library/remove-reference-class.md) on the resulting type.
302306

303307
```cpp
304308
// Example 4: different result types
309+
extern bool cond;
310+
extern int count;
305311
char a = 'A';
306312
const char b = 'B';
307313
decltype(auto) x = cond ? a : b; // char without, const char& with /Zc:ternary
308-
const char (&z)[2] = argc > 3 ? "A" : "B"; // const char* without /Zc:ternary
314+
const char (&z)[2] = count > 3 ? "A" : "B"; // const char* without /Zc:ternary
309315
```
310316
311-
#### Name dependency analysis
317+
#### Two-phase name look up (partial)
312318
313-
When the **/permissive-** option is set in Visual Studio 2017 Update 3, the compiler parses function and class template definitions, identifying dependent and non-dependent names used in templates as required for two-phase name look-up. In this release, only name dependency analysis is performed. In particular, non-dependent names that are not declared in the context of a template definition cause a diagnostic message as required by the ISO C++ standards. However, binding of non-dependent names that require argument dependent look up in the definition context is not done.
319+
When the **/permissive-** option is set in Visual Studio 2017 Update Version 15.3, the compiler parses function and class template definitions, identifying dependent and non-dependent names used in templates as required for two-phase name look-up. In this release, only name dependency analysis is performed. In particular, non-dependent names that are not declared in the context of a template definition cause a diagnostic message as required by the ISO C++ standards. However, binding of non-dependent names that require argument dependent look up in the definition context is not done.
314320
315321
```cpp
316-
// dependency.cpp
317-
// For previous behavior, compile with: cl /W4 dependency.cpp
318-
// For name dependency analysis, compile with: cl /W4 /permissive- dependency.cpp
319-
#include <stdio.h>
320-
321-
void f(long) {
322-
puts("Standard two-phase name dependency");
323-
}
324-
325-
template <typename T> void g(T t) {
326-
f(t);
327-
}
322+
// dependent base
323+
struct B {
324+
void g();
325+
};
328326
329-
void f(int) {
330-
puts("Microsoft one-phase name dependency");
331-
}
327+
template<typename T>
328+
struct D : T {
329+
void f() {
330+
// The call to g was incorrectly allowed in VS2017:
331+
g(); // Now under /permissive-: C3861
332+
// Possible fixes:
333+
// this->g();
334+
// T::g();
335+
}
336+
};
332337
333-
int main() {
334-
g(42);
338+
int main()
339+
{
340+
D<B> d;
341+
d.f();
335342
}
336343
```
337-
338344

339345
### To set this compiler option in the Visual Studio development environment
340346

docs/build/reference/std-specify-language-standard-version.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ Enable supported C++ language features from the specified version of the C++ lan
2222
## Syntax
2323

2424
```
25-
/std:[c++14|c++latest]
25+
/std:[c++14|c++17|c++latest]
2626
```
2727

2828
## Remarks
29-
The **/std** option is used to control the version-specific ISO C++ programming language standard features enabled during compilation of your code. This option allows you to disable support for certain new language and library features that may break your existing code that conforms to a particular version of the language standard. By default, **/std:c++14** is specified, which disables language and standard library features found in later versions of the C++ language standard. To explicitly enable the latest supported compiler and standard library features, use **/std:c++latest**.
3029

31-
The default **/std:c++14** option enables the set of C++14 features implemented by the Visual C++ compiler. This option disables compiler and standard library support for features that are changed or new in more recent versions of the language standard, with the exception of some C++17 features already implemented in previous releases of the Visual C++ compiler. To avoid breaking changes for users who have already taken dependencies on the features available as of Visual Studio 2015 Update 2, these features remain enabled when the **/std:c++14** option is specified:
30+
The **/std** option is used to control the version-specific ISO C++ programming language standard features enabled during compilation of your code. This option allows you to disable support for certain new language and library features that may break your existing code that conforms to a particular version of the language standard. By default, **/std:c++14** is specified, which disables language and standard library features found in later versions of the C++ language standard. To explicitly enable the latest supported compiler and standard library features, use **/std:c++latest**.
31+
32+
The default **/std:c++14** option enables the set of C++14 features implemented by the Visual C++ compiler. This option disables compiler and standard library support for features that are changed or new in more recent versions of the language standard, with the exception of some C++17 features already implemented in previous releases of the Visual C++ compiler. To avoid breaking changes for users who have already taken dependencies on the features available as of Visual Studio 2015 Update 2, these features remain enabled when the **/std:c++14** option is specified:
3233

3334
- [Rules for auto with braced-init-lists](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html)
3435

@@ -40,9 +41,11 @@ Enable supported C++ language features from the specified version of the C++ lan
4041

4142
- [u8 character literals](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4267.html)
4243

43-
The **/std:c++latest** option enables the set of C++ language and library features implemented by Visual C++ to track the most recent Working Draft and defect updates of the C++ Standard. Use this switch to get the latest language features supported by the compiler. For a list of supported language and library features, see [What's New for Visual C++](../../what-s-new-for-visual-cpp-in-visual-studio.md). The **/std:c++latest** option does not enable features guarded by the **/experimental** switch.
44+
The **/std:c++17** option enables the set of C++17 features implemented by the Visual C++ compiler. This option disables compiler and standard library support for features that are changed or new in more recent versions of the Working Draft and defect updates of the C++ Standard.
45+
46+
The **/std:c++latest** option enables the set of C++ language and library features implemented by Visual C++ to track the most recent Working Draft and defect updates of the C++ Standard. Use this switch to get the latest language features supported by the compiler. For a list of supported language and library features, see [What's New for Visual C++](../../what-s-new-for-visual-cpp-in-visual-studio.md). The **/std:c++latest** option does not enable features guarded by the **/experimental** switch.
4447

45-
The **/std:c++14** and **/std:c++latest** options are available beginning in Visual C++ 2015 Update 3.
48+
The **/std:c++14** and **/std:c++latest** options are available beginning in Visual C++ 2015 Update 3. The **/std:c++17** option is available beginning in Visual C++ 2017 Update Version 15.3.
4649

4750
> [!NOTE]
4851
> Depending on the Visual C++ compiler version or update level, certain C++14 features may not be fully implemented or fully conformant when you specify the **/std:c++14** option. For example, the Visual C++ 2017 RTM compiler does not fully support C++14-conformant `constexpr`, expression SFINAE, or 2-phase name lookup. For an overview of C++ language conformance in Visual C++, see [Visual C++ Language Conformance](../../visual-cpp-language-conformance.md).
@@ -56,5 +59,6 @@ Enable supported C++ language features from the specified version of the C++ lan
5659
3. In **Additional Options**, enter **/std:c++latest** to enable the latest language feature support, or **/std:c++14** to disable it and use only C++14 language features.
5760

5861
## See Also
59-
[Compiler Options](../../build/reference/compiler-options.md)
60-
[Setting Compiler Options](../../build/reference/setting-compiler-options.md)
62+
63+
[Compiler Options](../../build/reference/compiler-options.md)
64+
[Setting Compiler Options](../../build/reference/setting-compiler-options.md)

0 commit comments

Comments
 (0)