Skip to content

Commit 5a03e3d

Browse files
authored
Merge pull request #2274 from mikeblome/mb-conformance-162
new conformance updates for 16.2
2 parents e354c42 + 709fef9 commit 5a03e3d

1 file changed

Lines changed: 219 additions & 18 deletions

File tree

docs/overview/cpp-conformance-improvements.md

Lines changed: 219 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "C++ conformance improvements"
3-
ms.date: "06/14/2019"
3+
ms.date: "08/30/2019"
44
description: "Microsoft C++ in Visual Studio is progressing toward full conformance with the C++20 language standard."
55
ms.technology: "cpp-language"
66
author: "mikeblome"
@@ -10,11 +10,11 @@ ms.author: "mblome"
1010

1111
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. To jump directly to the changes for a specific version, use the **In this article** list.
1212

13-
::: moniker range=">=vs-2019"
13+
::: moniker range="vs-2019"
1414

15-
## <a name="improvements_160"></a> Improvements in Visual Studio 2019 RTW (version 16.0)
15+
## <a name="improvements_160"></a> Conformance improvements in Visual Studio 2019 RTW (version 16.0)
1616

17-
Visual Studio 2019 RTW contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C++ compiler (MSVC).
17+
Visual Studio 2019 RTW contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C++ compiler (MSVC)
1818

1919
**Note:** C++20 features will be made available in `/std:c++latest` mode until the C++20 implementation is complete for both the compiler and IntelliSense. At that time, the `/std:c++20` compiler mode will be introduced.
2020

@@ -156,7 +156,7 @@ Implemented the `remove_cvref` and `remove_cvref_t` type traits from [P0550](htt
156156

157157
[C++20 P1008R1 - prohibiting aggregates with user-declared constructors](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1008r1.pdf) is complete.
158158

159-
## <a name="improvements_161"></a> Improvements in Visual Studio 2019 version 16.1
159+
## <a name="improvements_161"></a> Conformance improvements in 16.1
160160

161161
### char8_t
162162

@@ -235,7 +235,154 @@ void f() {
235235
- `remove()`, `remove_if()`, and `unique()` for `list` and `forward_list` now return `size_type`.
236236
- `shift_left()` and `shift_right()` added to \<algorithm>.
237237

238-
## Bug fixes and behavior changes in Visual Studio 2019
238+
239+
## <a name="improvements_162"></a> Conformance improvements in 16.2
240+
241+
### noexcept constexpr functions
242+
243+
Constexpr functions are no longer considered `noexcept` by default when used in a constant expression. This behavior change comes from the resolution of [CWG 1351](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1351) and is enabled in [/permissive-](../build/reference/permissive-standards-conformance.md). The following example compiles in Visual Studio 2019 version 16.1 and earlier, but produces C2338 in Visual Studio 2019 version 16.2:
244+
245+
```cpp
246+
constexpr int f() { return 0; }
247+
248+
int main() {
249+
static_assert(noexcept(f()), "f should be noexcept"); // C2338 in 16.2
250+
}
251+
```
252+
253+
To fix the error, add the `noexcept` expression to the function declaration:
254+
255+
```cpp
256+
constexpr int f() noexcept { return 0; }
257+
258+
int main() {
259+
static_assert(noexcept(f()), "f should be noexcept");
260+
}
261+
```
262+
263+
### Binary expressions with different enum types
264+
265+
The ability to apply the usual arithmetic conversions on operands where one is of enumeration type and the other is of a different enumeration type or a floating-point type is deprecated in C++20 ([P1120R0](http://wg21.link/p1120r0)). In Visual Studio 2019 version 16.2 and later, the following code produces a level 4 warning when the [/std:c++latest](../build/reference/std-specify-language-standard-version.md) compiler option is enabled:
266+
267+
```cpp
268+
enum E1 { a };
269+
enum E2 { b };
270+
int main() {
271+
int i = a | b; // warning C5054: operator '|': deprecated between enumerations of different types
272+
}
273+
```
274+
275+
To avoid the warning, use [static_cast](../cpp/static-cast-operator.md) to convert the second operand:
276+
277+
```cpp
278+
enum E1 { a };
279+
enum E2 { b };
280+
int main() {
281+
int i = a | static_cast<int>(b);
282+
}
283+
```
284+
285+
### Binary expressions with enumeration and floating point types
286+
287+
The ability to apply the usual arithmetic conversions on operands where one is of enumeration type and the other is of a different enumeration type or a floating-point type is deprecated in C++20 ([P1120R0](http://wg21.link/p1120r0)). In other words, using a binary operation between an enumeration and a floating-point type is now a warning when the [/std:c++latest](../build/reference/std-specify-language-standard-version.md) compiler option is enabled:
288+
289+
```cpp
290+
enum E1 { a };
291+
int main() {
292+
double i = a * 1.1;
293+
}
294+
```
295+
296+
To avoid the warning, use [static_cast](../cpp/static-cast-operator.md) to convert the second operand:
297+
298+
```cpp
299+
enum E1 { a };
300+
int main() {
301+
double i = static_cast<int>(a) * 1.1;
302+
}
303+
```
304+
305+
### Equality and relational comparisons of arrays
306+
307+
Equality and relational comparisons between two operands of array type are deprecated in C++20 ([P1120R0](http://wg21.link/p1120r0)). In other words, a comparison operation between two arrays (regardless of rank and extent similarities) is a now a warning. Starting in Visual Studio 2019 version 16.2, the following code produces *C5056: operator '==': deprecated for array types* when the [/std:c++latest](../build/reference/std-specify-language-standard-version.md) compiler option is enabled:
308+
309+
```cpp
310+
int main() {
311+
int a[] = { 1, 2, 3 };
312+
int b[] = { 1, 2, 3 };
313+
if (a == b) { return 1; }
314+
}
315+
```
316+
317+
To avoid the warning, you can compare the addresses of the first elements:
318+
319+
```cpp
320+
int main() {
321+
int a[] = { 1, 2, 3 };
322+
int b[] = { 1, 2, 3 };
323+
if (&a[0] == &b[0]) { return 1; }
324+
}
325+
```
326+
327+
To determine whether the contents of two arrays are equal, use the [std::equal](../standard-library/algorithm-functions.md#equal) function:
328+
329+
```cpp
330+
std::equal(std::begin(a), std::end(a), std::begin(b), std::end(b));
331+
```
332+
333+
### Effect of defining spaceship operator on == and !=
334+
335+
A definition of the spaceship operator (**<=>**) alone will no longer rewrite expressions involving **==** or **!=** unless the spaceship operator is marked as `= default` ([P1185R2](https://wg21.link/p1185r2)). The following example compiles in Visual Studio 2019 RTW and version 16.1, but produces C2678 in Visual Studio 2019 version 16.2:
336+
337+
```cpp
338+
#include <compare>
339+
340+
struct S {
341+
int a;
342+
auto operator<=>(const S& rhs) const {
343+
return a <=> rhs.a;
344+
}
345+
};
346+
bool eq(const S& lhs, const S& rhs) {
347+
return lhs == rhs;
348+
}
349+
bool neq(const S& lhs, const S& rhs) {
350+
return lhs != rhs;
351+
}
352+
```
353+
354+
To avoid the error, define the operator== or declare it as defaulted:
355+
356+
```cpp
357+
#include <compare>
358+
359+
struct S {
360+
int a;
361+
auto operator<=>(const S& rhs) const {
362+
return a <=> rhs.a;
363+
}
364+
bool operator==(const S&) const = default;
365+
};
366+
bool eq(const S& lhs, const S& rhs) {
367+
return lhs == rhs;
368+
}
369+
bool neq(const S& lhs, const S& rhs) {
370+
return lhs != rhs;
371+
}
372+
```
373+
374+
### Standard Library improvements
375+
376+
- \<charconv> `to_chars()` with fixed/scientific precision. (General precision is currently planned for 16.4.)
377+
- [P0020R6](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0020r6.html): atomic\<float>, atomic\<double>, atomic\<long double>
378+
- [P0463R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0463r1.html): endian
379+
- [P0482R6](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r6.html): Library Support For char8_t
380+
- [P0600R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0600r1.pdf): [\[nodiscard]] For The STL, Part 1
381+
- [P0653R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r2.html): to_address()
382+
- [P0754R2](http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0754r2.pdf): \<version>
383+
- [P0771R1](http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0771r1.pdf): noexcept For std::function's move constructor
384+
385+
## <a name="update_160"></a> Bug fixes and behavior changes in Visual Studio 2019
239386
240387
### Correct diagnostics for basic_string range constructor
241388
@@ -515,11 +662,61 @@ Fixed a regression in `std::pair`'s assignment operator introduced when implemen
515662
516663
Fixed a minor type traits bug, where `add_const_t` and related functions are supposed to be a non-deduced context. In other words, `add_const_t` should be an alias for `typename add_const<T>::type`, not `const T`.
517664
665+
## <a name="update_162"></a> Bug fixes and behavior changes in 16.2
666+
667+
### Const comparators for associative containers
668+
669+
Code for search and insertion in [set](../standard-library/set-class.md), [map](../standard-library/map-class.md), [multiset](../standard-library/multiset-class.md), and [multimap](../standard-library/multimap-class.md) has been merged for reduced code size. Insertion operations now call the less-than comparison on a `const` comparison functor, in the same way that search operations have done previously. The following code compiles in Visual Studio 2019 version 16.1 and earlier, but raises C3848 in Visual Studio 2019 version 16.2:
670+
671+
```cpp
672+
#include <iostream>
673+
#include <map>
674+
675+
using namespace std;
676+
677+
struct K
678+
{
679+
int a;
680+
string b = "label";
681+
};
682+
683+
struct Comparer {
684+
bool operator() (K a, K b) {
685+
return a.a < b.a;
686+
}
687+
};
688+
689+
map<K, double, Comparer> m;
690+
691+
K const s1{1};
692+
K const s2{2};
693+
K const s3{3};
694+
695+
int main() {
696+
697+
m.emplace(s1, 1.08);
698+
m.emplace(s2, 3.14);
699+
m.emplace(s3, 5.21);
700+
701+
}
702+
```
703+
704+
To avoid the error, make the comparison operator `const`:
705+
706+
```cpp
707+
struct Comparer {
708+
bool operator() (K a, K b) const {
709+
return a.a < b.a;
710+
}
711+
};
712+
713+
```
714+
518715
::: moniker-end
519716
520-
::: moniker range=">=vs-2017"
717+
::: moniker range="vs-2017"
521718
522-
## <a name="improvements_150"></a> Improvements in Visual Studio 2017 RTW (version 15.0)
719+
## <a name="improvements_150"></a> Conformance improvements in Visual Studio 2017 RTW (version 15.0)
523720
524721
With support for generalized `constexpr` and non-static data member initialization (NSDMI) for aggregates, the Microsoft C++ compiler in Visual Studio 2017 is now complete for features added in the C++14 standard. However, the compiler still lacks a few features from the C++11 and C++98 standards. See [Visual C++ Language Conformance](../visual-cpp-language-conformance.md) for a table that shows the current state of the compiler.
525722
@@ -547,7 +744,7 @@ In **/std:c++17** mode, the `[[fallthrough]]` attribute can be used in the conte
547744
548745
Range-based for loops no longer require that `begin()` and `end()` return objects of the same type. This change enables `end()` to return a sentinel as used by ranges in [range-v3](https://github.com/ericniebler/range-v3) and the completed-but-not-quite-published Ranges Technical Specification. For more information, see [Generalizing the Range-Based For Loop](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html).
549746
550-
## <a name="improvements_153"></a> Improvements in Visual Studio 2017 version 15.3
747+
## <a name="improvements_153"></a> Conformance improvements in 15.3
551748
552749
### constexpr lambdas
553750
@@ -589,7 +786,7 @@ The `*this` object in a lambda expression may now be captured by value. This cha
589786
590787
The `register` keyword, previously deprecated (and ignored by the compiler), is now removed from the language. For more information, see [Remove Deprecated Use of the register Keyword](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0001r1.html).
591788
592-
## <a name="improvements_155"></a> Improvements in Visual Studio 2017 version 15.5
789+
## <a name="improvements_155"></a> Conformance improvements in 15.5
593790
594791
Features marked with \[14] are available unconditionally even in **/std:c++14** mode.
595792
@@ -653,7 +850,7 @@ The standard library now uses variable templates internally.
653850
654851
The standard library has been updated in response to C++17 compiler changes, including the addition of `noexcept` in the type system and the removal of dynamic-exception-specifications.
655852
656-
## <a name="improvements_156"></a> Improvements in Visual Studio 2017 version 15.6
853+
## <a name="improvements_156"></a> Conformance improvements in 15.6
657854
658855
### C++17 Library Fundamentals V1
659856
@@ -663,7 +860,7 @@ The standard library has been updated in response to C++17 compiler changes, inc
663860
664861
[P0739R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0739r0.html) Move `adopt_lock_t` to front of parameter list for `scoped_lock` to enable consistent use of `scoped_lock`. Allow `std::variant` constructor to participate in overload resolution in more cases, to enable copy assignment.
665862
666-
## <a name="improvements_157"></a> Improvements in Visual Studio 2017 version 15.7
863+
## <a name="improvements_157"></a> Conformance improvements in 15.7
667864
668865
### C++17: Rewording inheriting constructors
669866
@@ -835,7 +1032,7 @@ void sample(A<0> *p)
8351032

8361033
[P0426R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0426r1.html) Changes to `std::traits_type` member functions `length`, `compare`, and `find` to make `std::string_view` usable in constant expressions. (In Visual Studio 2017 version 15.6, supported for Clang/LLVM only. In version 15.7 Preview 2, support is nearly complete for ClXX as well.)
8371034

838-
## <a name="improvements_159"></a> Improvements in Visual Studio 2017 version 15.9
1035+
## <a name="improvements_159"></a> Conformance improvements in 15.9
8391036

8401037
### Left-to-right evaluation order for operators `->*`, `[]`, `>>`, and `<<`
8411038

@@ -1192,7 +1389,7 @@ void f(ClassLibrary1::Class1 ^r1, ClassLibrary1::Class2 ^r2)
11921389
}
11931390
```
11941391

1195-
## <a name="update_153"></a> Bug fixes in Visual Studio 2017 version 15.3
1392+
## <a name="update_153"></a> Bug fixes in 15.3
11961393

11971394
### Calls to deleted member templates
11981395

@@ -1564,7 +1761,7 @@ To fix the problem, arrange the initializer list to have the same order as the d
15641761

15651762
This warning is off-by-default, and only affects code compiled with **/Wall**.
15661763

1567-
## <a name="update_155"></a> Bug fixes and other behavior changes in Visual Studio 2017 version 15.5
1764+
## <a name="update_155"></a> Bug fixes and other behavior changes in 15.5
15681765

15691766
### Partial ordering change
15701767

@@ -2023,7 +2220,7 @@ int main()
20232220
}
20242221
```
20252222
2026-
## <a name="update_157"></a> Bug fixes and other behavior changes in Visual Studio 2017 version 15.7
2223+
## <a name="update_157"></a> Bug fixes and other behavior changes in 15.7
20272224
20282225
### C++17: Default argument in the primary class template
20292226
@@ -2159,7 +2356,7 @@ int main() {
21592356
}
21602357
```
21612358

2162-
## <a name="update_158"></a> Bug fixes and behavior changes in Visual Studio 2017 version 15.8
2359+
## <a name="update_158"></a> Bug fixes and behavior changes in 15.8
21632360

21642361
The compiler changes in Visual Studio 2017 version 15.8 all fall under the category of bug fixes and behavior changes, and are listed below:
21652362

@@ -2366,7 +2563,7 @@ struct X : Base<T>
23662563
};
23672564
```
23682565

2369-
## <a name="update_159"></a> Bug fixes and behavior changes in Visual Studio 2017 version 15.9
2566+
## <a name="update_159"></a> Bug fixes and behavior changes in 15.9
23702567

23712568
### Identifiers in member alias templates
23722569

@@ -2551,10 +2748,14 @@ To avoid the error, remove the `constexpr` qualifier from the explicit instantia
25512748

25522749
::: moniker-end
25532750

2751+
::: moniker range="vs-2015"
2752+
25542753
## C++ conformance improvements in Visual Studio 2015
25552754

25562755
For the complete list of conformance improvements up through Visual Studio 2015 Update 3, see [Visual C++ What's New 2003 through 2015](/cpp/porting/visual-cpp-what-s-new-2003-through-2015).
25572756

2757+
::: moniker-end
2758+
25582759
## See also
25592760

25602761
[Visual C++ language conformance](../visual-cpp-language-conformance.md)

0 commit comments

Comments
 (0)