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/overview/cpp-conformance-improvements.md
+22-22Lines changed: 22 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ ms.author: "mblome"
8
8
---
9
9
# C++ conformance improvements in Visual Studio
10
10
11
-
Microsoft C++ makes conformance improvements in every release. This article lists the improvements by major release, then by version. It also lists major bug fixes by version.
11
+
Microsoft C++ makes conformance improvements and bug fixes in every release. This article lists the improvements by major release, then by version. It also lists major bug fixes by version.
12
12
13
13
::: moniker range=">=vs-2019"
14
14
@@ -162,7 +162,7 @@ Implemented the `remove_cvref` and `remove_cvref_t` type traits from [P0550](htt
162
162
163
163
### char8_t
164
164
165
-
[P0482r6](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r6.html). C++20 adds a new character type that is used to represent UTF-8 code units. `u8` string literals in C++20 have type `const char8_t[N]` instead of `const char[N]`, which was the case previously. Similar changes have been proposed for the C standard in [N2231](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2231.htm). Suggestions for `char8_t` backward compatibility remediation are given in [P1423r0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r0.html). The Microsoft C++ compiler adds support for `char8_t` in Visual Studio 2019 version 16.1 when you specify the **/Zc:char8_t** compiler option. In the future, it will be supported with [/std:c++latest](../../build/reference/std-specify-language-standard-version.md), which can be reverted to C++17 behavior via **/Zc:char8_t-**. The EDG compiler that powers IntelliSense doesn't yet support it, so you'll see spurious IntelliSense-only errors that don't impact the actual compilation.
165
+
[P0482r6](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r6.html). C++20 adds a new character type that is used to represent UTF-8 code units. `u8` string literals in C++20 have type `const char8_t[N]` instead of `const char[N]`, which was the case previously. Similar changes have been proposed for the C standard in [N2231](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2231.htm). Suggestions for `char8_t` backward compatibility remediation are given in [P1423r0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r0.html). The Microsoft C++ compiler adds support for `char8_t` in Visual Studio 2019 version 16.1 when you specify the **/Zc:char8_t** compiler option. In the future, it will be supported with [/std:c++latest](../build/reference/std-specify-language-standard-version.md), which can be reverted to C++17 behavior via **/Zc:char8_t-**. The EDG compiler that powers IntelliSense doesn't yet support it, so you'll see spurious IntelliSense-only errors that don't impact the actual compilation.
### std::type_identity metafunction and std::identity function object
175
175
176
-
[P0887R1 type_identity](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0887r1.pdf). The deprecated `std::identity` class template extension has been removed, and replaced with the C++20 `std::type_identity` metafunction and `std::identity` function object. Both are available only under [/std:c++latest](../../build/reference/std-specify-language-standard-version.md).
176
+
[P0887R1 type_identity](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0887r1.pdf). The deprecated `std::identity` class template extension has been removed, and replaced with the C++20 `std::type_identity` metafunction and `std::identity` function object. Both are available only under [/std:c++latest](../build/reference/std-specify-language-standard-version.md).
177
177
178
178
The following example produces deprecation warning C4996 for `std::identity` (defined in \<type_traits>) in Visual Studio 2017:
179
179
@@ -200,7 +200,7 @@ long j = static_cast<long>(i);
200
200
201
201
### Syntax checks for generic lambdas
202
202
203
-
The new lambda processor enables some conformance-mode syntactic checks in generic lambdas, under [/std:c++latest](../../build/reference/std-specify-language-standard-version.md) or under any other language mode with **/experimental:newLambdaProcessor**.
203
+
The new lambda processor enables some conformance-mode syntactic checks in generic lambdas, under [/std:c++latest](../build/reference/std-specify-language-standard-version.md) or under any other language mode with **/experimental:newLambdaProcessor**.
204
204
205
205
In Visual Studio 2017, this code compiles without warnings, but in Visual Studio 2019 it produces error *C2760 syntax error: unexpected token '\<id-expr>', expected 'id-expression'*:
206
206
@@ -551,31 +551,31 @@ Range-based for loops no longer require that `begin()` and `end()` return object
551
551
552
552
### constexpr lambdas
553
553
554
-
Lambda expressions may now be used in constant expressions. For more information, see [constexpr lambda expressions in C++](../../cpp/lambda-expressions-constexpr.md).
554
+
Lambda expressions may now be used in constant expressions. For more information, see [constexpr lambda expressions in C++](../cpp/lambda-expressions-constexpr.md).
555
555
556
556
### `if constexpr` in function templates
557
557
558
-
A function template may contain `if constexpr` statements to enable compile-time branching. For more information, see [if constexpr statements](../../cpp/if-else-statement-cpp.md#if_constexpr).
558
+
A function template may contain `if constexpr` statements to enable compile-time branching. For more information, see [if constexpr statements](../cpp/if-else-statement-cpp.md#if_constexpr).
559
559
560
560
### Selection statements with initializers
561
561
562
-
An `if` statement may include an initializer that introduces a variable at block scope within the statement itself. For more information, see [if statements with initializer](../../cpp/if-else-statement-cpp.md#if_with_init).
562
+
An `if` statement may include an initializer that introduces a variable at block scope within the statement itself. For more information, see [if statements with initializer](../cpp/if-else-statement-cpp.md#if_with_init).
563
563
564
564
### `[[maybe_unused]]` and `[[nodiscard]]` attributes
565
565
566
-
New attribute `[[maybe_unused]]` silences warnings when an entity isn't used. The `[[nodiscard]]` attribute creates a warning if the return value of a function call is discarded. For more information, see [Attributes in C++](../../cpp/attributes.md).
566
+
New attribute `[[maybe_unused]]` silences warnings when an entity isn't used. The `[[nodiscard]]` attribute creates a warning if the return value of a function call is discarded. For more information, see [Attributes in C++](../cpp/attributes.md).
567
567
568
568
### Using attribute namespaces without repetition
569
569
570
-
New syntax to enable only a single namespace identifier in an attribute list. For more information, see [Attributes in C++](../../cpp/attributes.md).
570
+
New syntax to enable only a single namespace identifier in an attribute list. For more information, see [Attributes in C++](../cpp/attributes.md).
571
571
572
572
### Structured bindings
573
573
574
-
It's now possible in a single declaration to store a value with individual names for its components, when the value is an array, a `std::tuple` or `std::pair`, or has all public non-static data members. For more information, see [Structured Bindings](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0144r0.pdf) and [Returning multiple values from a function](../../cpp/functions-cpp.md#multi_val).
574
+
It's now possible in a single declaration to store a value with individual names for its components, when the value is an array, a `std::tuple` or `std::pair`, or has all public non-static data members. For more information, see [Structured Bindings](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0144r0.pdf) and [Returning multiple values from a function](../cpp/functions-cpp.md#multi_val).
575
575
576
576
### Construction rules for `enum class` values
577
577
578
-
There's now an implicit/non-narrowing conversion from a scoped enumeration's underlying type to the enumeration itself, when its definition introduces no enumerator and the source uses a list-initialization syntax. For more information, see [Construction Rules for enum class Values](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0138r2.pdf) and [Enumerations](../../cpp/enumerations-cpp.md#no_enumerators).
578
+
There's now an implicit/non-narrowing conversion from a scoped enumeration's underlying type to the enumeration itself, when its definition introduces no enumerator and the source uses a list-initialization syntax. For more information, see [Construction Rules for enum class Values](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0138r2.pdf) and [Enumerations](../cpp/enumerations-cpp.md#no_enumerators).
579
579
580
580
### Capturing `*this` by value
581
581
@@ -595,7 +595,7 @@ Features marked with \[14] are available unconditionally even in **/std:c++14**
595
595
596
596
### New compiler switch for `extern constexpr`
597
597
598
-
In earlier versions of Visual Studio, the compiler always gave a `constexpr` variable internal linkage even when the variable was marked `extern`. In Visual Studio 2017 version 15.5, a new compiler switch, [/Zc:externConstexpr](../../build/reference/zc-externconstexpr.md), enables correct standards-conforming behavior. For more information, see [extern constexpr linkage](#extern_linkage).
598
+
In earlier versions of Visual Studio, the compiler always gave a `constexpr` variable internal linkage even when the variable was marked `extern`. In Visual Studio 2017 version 15.5, a new compiler switch, [/Zc:externConstexpr](../build/reference/zc-externconstexpr.md), enables correct standards-conforming behavior. For more information, see [extern constexpr linkage](#extern_linkage).
599
599
600
600
### Removing dynamic exception specifications
601
601
@@ -707,7 +707,7 @@ struct B : A {
707
707
B b(42L); // now calls B(int)
708
708
```
709
709
710
-
For more information, see [Constructors](../../cpp/constructors-cpp.md#inheriting_constructors).
710
+
For more information, see [Constructors](../cpp/constructors-cpp.md#inheriting_constructors).
711
711
712
712
### C++17: Extended aggregate initialization
713
713
@@ -1456,7 +1456,7 @@ The warning is excluded under **/Wv:18** and is on by default under warning leve
1456
1456
1457
1457
### `std::is_convertible` for array types
1458
1458
1459
-
Previous versions of the compiler gave incorrect results for [std::is_convertible](../../standard-library/is-convertible-class.md) for array types. This required library writers to special-case the Microsoft C++ compiler when using the `std::is_convertible<...>` type trait. In the following example, the static asserts pass in earlier versions of Visual Studio but fail in Visual Studio 2017 version 15.3:
1459
+
Previous versions of the compiler gave incorrect results for [std::is_convertible](../standard-library/is-convertible-class.md) for array types. This required library writers to special-case the Microsoft C++ compiler when using the `std::is_convertible<...>` type trait. In the following example, the static asserts pass in earlier versions of Visual Studio but fail in Visual Studio 2017 version 15.3:
### Private destructors and `std::is_constructible`
1479
1479
1480
-
Previous versions of the compiler ignored whether a destructor was private when deciding the result of [std::is_constructible](../../standard-library/is-constructible-class.md). It now considers them. In the following example, the static asserts pass in earlier versions of Visual Studio but fail in Visual Studio 2017 version 15.3:
1480
+
Previous versions of the compiler ignored whether a destructor was private when deciding the result of [std::is_constructible](../standard-library/is-constructible-class.md). It now considers them. In the following example, the static asserts pass in earlier versions of Visual Studio but fail in Visual Studio 2017 version 15.3:
1481
1481
1482
1482
```cpp
1483
1483
#include <type_traits>
@@ -2165,7 +2165,7 @@ The compiler changes in Visual Studio 2017 version 15.8 all fall under the categ
2165
2165
2166
2166
### `typename` on unqualified identifiers
2167
2167
2168
-
In [/permissive-](../../build/reference/permissive-standards-conformance.md) mode, spurious `typename` keywords on unqualified identifiers in alias template definitions are no longer accepted by the compiler. The following code now produces C7511 *'T': 'typename' keyword must be followed by a qualified name*:
2168
+
In [/permissive-](../build/reference/permissive-standards-conformance.md) mode, spurious `typename` keywords on unqualified identifiers in alias template definitions are no longer accepted by the compiler. The following code now produces C7511 *'T': 'typename' keyword must be followed by a qualified name*:
2169
2169
2170
2170
```cpp
2171
2171
template <typename T>
@@ -2176,9 +2176,9 @@ To fix the error, change the second line to `using X = T;`.
2176
2176
2177
2177
### `__declspec()` on right side of alias template definitions
2178
2178
2179
-
[__declspec](../../cpp/declspec.md) is no longer permitted on the right-hand-side of an alias template definition. This code was previously accepted but ignored by the compiler, and would never result in a deprecation warning when the alias was used.
2179
+
[__declspec](../cpp/declspec.md) is no longer permitted on the right-hand-side of an alias template definition. This code was previously accepted but ignored by the compiler, and would never result in a deprecation warning when the alias was used.
2180
2180
2181
-
The standard C++ attribute [\[\[deprecated\]\]](../../cpp/attributes.md) may be used instead, and is respected in Visual Studio 2017 version 15.6. The following code now produces C2760 *syntax error: unexpected token '__declspec', expected 'type specifier'*:
2181
+
The standard C++ attribute [\[\[deprecated\]\]](../cpp/attributes.md) may be used instead, and is respected in Visual Studio 2017 version 15.6. The following code now produces C2760 *syntax error: unexpected token '__declspec', expected 'type specifier'*:
2182
2182
2183
2183
```cpp
2184
2184
template <typename T>
@@ -2216,7 +2216,7 @@ struct S : Base<T> {
2216
2216
2217
2217
To fix the error, change the `return` statement to `return this->base_value;`.
2218
2218
2219
-
**Note:** In the Boost python library, there has been for a long time an MSVC-specific workaround for a template forward declaration in [unwind_type.hpp](https://github.com/boostorg/python/blame/develop/include/boost/python/detail/unwind_type.hpp). Under [/permissive-](../../build/reference/permissive-standards-conformance.md) mode starting with Visual Studio 2017 version 15.8 (_MSC_VER=1915), the MSVC compiler does argument-dependent name lookup (ADL) correctly and is consistent with other compilers, making this workaround guard unnecessary. To avoid error *C3861: 'unwind_type': identifier not found*, see [PR 229](https://github.com/boostorg/python/pull/229) in the Boost repo to update the header file. We've already patched the [vcpkg](../../build/vcpkg.md) Boost package, so if you get or upgrade your Boost sources from vcpkg then you don't need to apply the patch separately.
2219
+
**Note:** In the Boost python library, there has been for a long time an MSVC-specific workaround for a template forward declaration in [unwind_type.hpp](https://github.com/boostorg/python/blame/develop/include/boost/python/detail/unwind_type.hpp). Under [/permissive-](../build/reference/permissive-standards-conformance.md) mode starting with Visual Studio 2017 version 15.8 (_MSC_VER=1915), the MSVC compiler does argument-dependent name lookup (ADL) correctly and is consistent with other compilers, making this workaround guard unnecessary. To avoid error *C3861: 'unwind_type': identifier not found*, see [PR 229](https://github.com/boostorg/python/pull/229) in the Boost repo to update the header file. We've already patched the [vcpkg](../build/vcpkg.md) Boost package, so if you get or upgrade your Boost sources from vcpkg then you don't need to apply the patch separately.
2220
2220
2221
2221
### forward declarations and definitions in namespace `std`
2222
2222
@@ -2240,7 +2240,7 @@ To fix the error, use an **include** directive rather than a forward declaration
2240
2240
2241
2241
### Constructors that delegate to themselves
2242
2242
2243
-
The C++ standard suggests that a compiler should emit a diagnostic when a delegating constructor delegates to itself. The Microsoft C++ compiler in [/std:c++17](../../build/reference/std-specify-language-standard-version.md) and [/std:c++latest](../../build/reference/std-specify-language-standard-version.md) modes now raises C7535: *'X::X': delegating constructor calls itself*.
2243
+
The C++ standard suggests that a compiler should emit a diagnostic when a delegating constructor delegates to itself. The Microsoft C++ compiler in [/std:c++17](../build/reference/std-specify-language-standard-version.md) and [/std:c++latest](../build/reference/std-specify-language-standard-version.md) modes now raises C7535: *'X::X': delegating constructor calls itself*.
2244
2244
2245
2245
Without this error, the following program will compile but will generate an infinite loop:
2246
2246
@@ -2265,9 +2265,9 @@ public:
2265
2265
2266
2266
### `offsetof` with constant expressions
2267
2267
2268
-
[offsetof](../../c-runtime-library/reference/offsetof-macro.md) has traditionally been implemented using a macro that requires a [reinterpret_cast](../../cpp/reinterpret-cast-operator.md). This usage is illegal in contexts that require a constant expression, but the Microsoft C++ compiler has traditionally allowed it. The `offsetof` macro that is shipped as part of the standard library correctly uses a compiler intrinsic (**__builtin_offsetof**), but many people have used the macro trick to define their own `offsetof`.
2268
+
[offsetof](../c-runtime-library/reference/offsetof-macro.md) has traditionally been implemented using a macro that requires a [reinterpret_cast](../cpp/reinterpret-cast-operator.md). This usage is illegal in contexts that require a constant expression, but the Microsoft C++ compiler has traditionally allowed it. The `offsetof` macro that is shipped as part of the standard library correctly uses a compiler intrinsic (**__builtin_offsetof**), but many people have used the macro trick to define their own `offsetof`.
2269
2269
2270
-
In Visual Studio 2017 version 15.8, the compiler constrains the areas that these `reinterpret_cast` operators can appear in the default mode, to help code conform to standard C++ behavior. Under [/permissive-](../../build/reference/permissive-standards-conformance.md), the constraints are even stricter. Using the result of an `offsetof` in places that require constant expressions may result in code that issues warning C4644 *usage of the macro-based offsetof pattern in constant expressions is non-standard; use offsetof defined in the C++ standard library instead* or C2975 *invalid template argument, expected compile-time constant expression*.
2270
+
In Visual Studio 2017 version 15.8, the compiler constrains the areas that these `reinterpret_cast` operators can appear in the default mode, to help code conform to standard C++ behavior. Under [/permissive-](../build/reference/permissive-standards-conformance.md), the constraints are even stricter. Using the result of an `offsetof` in places that require constant expressions may result in code that issues warning C4644 *usage of the macro-based offsetof pattern in constant expressions is non-standard; use offsetof defined in the C++ standard library instead* or C2975 *invalid template argument, expected compile-time constant expression*.
2271
2271
2272
2272
The following code raises C4644 in **/default** and **/std:c++17** modes, and C2975 in **/permissive-** mode:
0 commit comments