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/cpp-conformance-improvements-2017.md
+99Lines changed: 99 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -586,5 +586,104 @@ To remove the warnings, simply comment-out or remove the empty declarations. In
586
586
The warning is excluded under /Wv:18 and is on by default under warning level W2.
587
587
588
588
589
+
### std::is_convertible for array types
590
+
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 Visual C++ compiler when using the `std::is_convertable<…>` type trait. In the following example, the static asserts pass in earlier versions of Visual Studio but fail in Visual Studio 2017 Update Version 15.3:
**std::is_convertible<From, To>** is calculated by checking to see if an imaginary function definition is well formed:
604
+
```cpp
605
+
To test() { return std::declval<From>(); }
606
+
```
607
+
608
+
### Private destructors and std::is_constructible
609
+
Previous versions of the compiler ignore whether a destructor was private when decided 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 Update Version 15.3:
610
+
611
+
```cpp
612
+
#include <type_traits>
613
+
614
+
class PrivateDtor {
615
+
PrivateDtor(int) { }
616
+
private:
617
+
~PrivateDtor() { }
618
+
};
619
+
620
+
// This assertion used to succeed. It now correctly fails.
Private destructors cause a type to be non-constructible. **std::is_constructible<T, Args…>** is calculated as if the following declaration were written:
625
+
```cpp
626
+
T obj(std::declval<Args>()…)
627
+
```
628
+
This call implies a destructor call.
629
+
630
+
### C2668: Ambiguous overload resolution
631
+
Previous versions of the compiler sometimes failed to detect ambiguity when it found multiple candidates via both using declarations and argument dependent lookups. This can lead to wrong overload being chosen and unexpected runtime behavior. In the following example, Visual Studio 2017 Update Version 15.3 correctly raises C2668 'f': ambiguous call to overloaded function:
632
+
633
+
```cpp
634
+
namespace N {
635
+
template<class T>
636
+
void f(T&, T&);
637
+
638
+
template<class T>
639
+
void f();
640
+
}
641
+
642
+
template<class T>
643
+
void f(T&, T&);
644
+
645
+
struct S {};
646
+
void f()
647
+
{
648
+
using N::f;
649
+
650
+
S s1, s2;
651
+
f(s1, s2);
652
+
}
653
+
```
654
+
To fix the code, remove the using N::f statement if you intended to call ::f().
655
+
656
+
### C2660: local function declarations and argument dependent lookup
657
+
Local function declarations hide the function declaration in the enclosing scope and disable argument dependent lookup.
658
+
However, previous versions of the Visual C++ compiler performed argument dependent lookup in this case, potentially leading to the wrong overload being chosen and unexpected runtime behavior. Typically, the error is due to an incorrect signature of the local function declaration. In the following example, Visual Studio 2017 Update Version 15.3 correctly raises C2660 'f': function does not take 2 arguments:
659
+
660
+
```cpp
661
+
structS {};
662
+
void f(S, int);
663
+
664
+
void g()
665
+
{
666
+
void f(S); // or void f(S, int);
667
+
S s;
668
+
f(s, 0);
669
+
}
670
+
```
671
+
672
+
To fix the problem, either change the **f(S)** signature or remove it.
673
+
674
+
### C5038: order of initialization in initializer lists
675
+
Class members are initialized in the order they are declared, not the order they appear in initializer lists. Previous versions of the compiler did not warn when the order of the initializer list differed from the order of declaration. This could lead to undefined runtime behavior if the intialization of one member depended on another member in the list already being initialized. In the following example, Visual Studio 2017 Update Version 15.3 raises warning C5038 warning C5038: data member 'A::y' will be initialized after data member 'A::x':
676
+
677
+
```cpp
678
+
struct A
679
+
{
680
+
A(int a) : y(a), x(y) {} // Initialized in reverse, y reused
681
+
int x;
682
+
int y;
683
+
};
684
+
685
+
```
686
+
To fix the problem arrange the intializer list to have the same order as the declarations. A similar warning is raised when one or both initializers refer to base class members.
687
+
589
688
## See Also
590
689
[Visual C++ Language Conformance](visual-cpp-language-conformance.md)
0 commit comments