Skip to content

Commit b1a5dfb

Browse files
author
mikeblome
committed
added new items for 15.3 per product team
1 parent 150153e commit b1a5dfb

1 file changed

Lines changed: 99 additions & 0 deletions

File tree

docs/cpp-conformance-improvements-2017.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,5 +586,104 @@ To remove the warnings, simply comment-out or remove the empty declarations. In
586586
The warning is excluded under /Wv:18 and is on by default under warning level W2.
587587
588588
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:
591+
592+
```cpp
593+
#include <type_traits>
594+
595+
using Array = char[1];
596+
597+
static_assert(std::is_convertible<Array, Array>::value);
598+
static_assert((std::is_convertible<const Array, const Array>::value), "");
599+
static_assert((std::is_convertible<Array&, Array>::value), "");
600+
static_assert((std::is_convertible<Array, Array&>::value), "");
601+
```
602+
603+
**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.
621+
static_assert(std::is_constructible<PrivateDtor, int>::value);
622+
```
623+
624+
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+
struct S {};
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+
589688
## See Also
590689
[Visual C++ Language Conformance](visual-cpp-language-conformance.md)

0 commit comments

Comments
 (0)