| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d9b1dde commit c9d2247
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -53,13 +53,13 @@ By default, the **/permissive-** option is not set. When the option is set, the | |||
| 53 | 53 | ||
| 54 | 54 | 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. | |
| 55 | 55 | ||
| 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. | ||
| 57 | 57 | ||
| 58 | 58 | 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. | |
| 59 | 59 | ||
| 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. | ||
| 61 | 61 | ||
| 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). | ||
| 63 | 63 | ||
| 64 | 64 | ### How to fix your code | |
| 65 | 65 | 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, | |||
| 238 | 238 | ||
| 239 | 239 | #### Ambiguous conditional operator arguments | |
| 240 | 240 | ||
| 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. | ||
| 242 | 242 | ||
| 243 | 243 | Commmon errors that may result from this change include: | |
| 244 | 244 | ||
@@ -264,13 +264,13 @@ extern bool cond; | |||
| 264 | 264 | ||
| 265 | 265 | A a(42); | |
| 266 | 266 | // 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 | ||
| 268 | 268 | // Accepted always: | |
| 269 | 269 | auto y = cond ? 7 : int(a); | |
| 270 | 270 | auto z = cond ? A(7) : a; | |
| 271 | 271 | ``` | |
| 272 | 272 | ||
| 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. | ||
| 274 | 274 | ||
| 275 | 275 | ```cpp | |
| 276 | 276 | // Example 2: exception from the above | |
@@ -279,11 +279,15 @@ struct MyString | |||
| 279 | 279 | MyString(const char* s = "") noexcept; // from char* | |
| 280 | 280 | operator const char* () const noexcept; // to char* | |
| 281 | 281 | }; | |
| 282 | + | ||
| 283 | + extern bool cond; | ||
| 282 | 284 | ||
| 283 | 285 | 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: | ||
| 287 | 291 | auto y = cond ? "A" : static_cast<const char*>(s); | |
| 288 | 292 | ``` | |
| 289 | 293 | ||
@@ -293,48 +297,50 @@ Another case where you may see errors is in conditional optators with one argume | |||
| 293 | 297 | // Example 3: void arguments | |
| 294 | 298 | void myassert(const char* text, const char* file, int line); | |
| 295 | 299 | // 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__)) | ||
| 297 | 301 | // 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__)) | ||
| 299 | 303 | ``` | |
| 300 | 304 | ||
| 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. | ||
| 302 | 306 | ||
| 303 | 307 | ```cpp | |
| 304 | 308 | // Example 4: different result types | |
| 309 | + extern bool cond; | ||
| 310 | + extern int count; | ||
| 305 | 311 | char a = 'A'; | |
| 306 | 312 | const char b = 'B'; | |
| 307 | 313 | 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 | ||
| 309 | 315 | ``` | |
| 310 | 316 | ||
| 311 | - #### Name dependency analysis | ||
| 317 | + #### Two-phase name look up (partial) | ||
| 312 | 318 | ||
| 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. | ||
| 314 | 320 | ||
| 315 | 321 | ```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 | + }; | ||
| 328 | 326 | ||
| 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 | + }; | ||
| 332 | 337 | ||
| 333 | - int main() { | ||
| 334 | - g(42); | ||
| 338 | + int main() | ||
| 339 | + { | ||
| 340 | + D<B> d; | ||
| 341 | + d.f(); | ||
| 335 | 342 | } | |
| 336 | 343 | ``` | |
| 337 | - | ||
| 338 | 344 | ||
| 339 | 345 | ### To set this compiler option in the Visual Studio development environment | |
| 340 | 346 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,13 +22,14 @@ Enable supported C++ language features from the specified version of the C++ lan | |||
| 22 | 22 | ## Syntax | |
| 23 | 23 | ||
| 24 | 24 | ``` | |
| 25 | - /std:[c++14|c++latest] | ||
| 25 | + /std:[c++14|c++17|c++latest] | ||
| 26 | 26 | ``` | |
| 27 | 27 | ||
| 28 | 28 | ## 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**. | ||
| 30 | 29 | ||
| 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: | ||
| 32 | 33 | ||
| 33 | 34 | - [Rules for auto with braced-init-lists](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html) | |
| 34 | 35 | ||
@@ -40,9 +41,11 @@ Enable supported C++ language features from the specified version of the C++ lan | |||
| 40 | 41 | ||
| 41 | 42 | - [u8 character literals](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4267.html) | |
| 42 | 43 | ||
| 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. | ||
| 44 | 47 | ||
| 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. | ||
| 46 | 49 | ||
| 47 | 50 | > [!NOTE] | |
| 48 | 51 | > 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 | |||
| 56 | 59 | 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. | |
| 57 | 60 | ||
| 58 | 61 | ## 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) | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments