Skip to content

Commit 530f6ae

Browse files
authored
Merge pull request #291 from Microsoft/mb-conform4
Updates for 15.3 preview 2
2 parents d272913 + f3a8763 commit 530f6ae

File tree

2 files changed

+117
-14
lines changed

2 files changed

+117
-14
lines changed

docs/cpp-conformance-improvements-2017.md

Lines changed: 116 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
---
22
title: "C++ compiler conformance improvements | Microsoft Docs"
33
ms.custom: ""
4-
ms.date: "11/16/2016"
4+
ms.date: "06/05/2017"
55
ms.reviewer: ""
66
ms.suite: ""
77
ms.technology:
88
- "vs-ide-general"
99
ms.tgt_pltfrm: ""
1010
ms.topic: "article"
1111
ms.assetid: 8801dbdb-ca0b-491f-9e33-01618bff5ae9
12-
author: "BrianPeek"
13-
ms.author: "brpeek"
12+
author: "mikeblome"
13+
ms.author: "mblome"
1414
manager: "ghogen"
1515
translation.priority.ht:
1616
- "cs-cz"
@@ -143,7 +143,7 @@ int main()
143143
```
144144

145145
### constexpr
146-
Visual Studio 2017 correctly raises an error when the left-hand operand of a conditionally evaluating operation is not valid in a constexpr context. The following code compiles in Visual Studio 2015 but not in Visual Studio 2017:
146+
Visual Studio 2017 correctly raises an error when the left-hand operand of a conditionally evaluating operation is not valid in a constexpr context. The following code compiles in Visual Studio 2015 but not in Visual Studio 2017 (C3615 constexpr function 'f' cannot result in a constant expression):
147147

148148
```cpp
149149
template<int N>
@@ -154,7 +154,7 @@ struct array
154154

155155
constexpr bool f(const array<1> &arr)
156156
{
157-
return arr.size() == 10 || arr.size() == 11; // error starting in Visual Studio 2017
157+
return arr.size() == 10 || arr.size() == 11; // C3615
158158
}
159159
```
160160
To correct the error, either declare the array::size() function as constexpr or remove the constexpr qualifier from f.
@@ -372,8 +372,8 @@ Visual Studio 2017 Update Version 15.3 improves pre-condition checks for type-tr
372372
struct S;
373373
enum E;
374374
375-
static_assert(!__is_assignable(S, S), "fail"); // this is allowed in VS2017 RTM, but should fail
376-
static_assert(__is_convertible_to(E, E), "fail"); // this is allowed in VS2017 RTM, but should fail
375+
static_assert(!__is_assignable(S, S), "fail"); // C2139 in 15.3
376+
static_assert(__is_convertible_to(E, E), "fail"); // C2139 in 15.3
377377
```
378378

379379
### New compiler warning and runtime checks on native-to-managed marshaling
@@ -416,7 +416,7 @@ To fix the error, remove the `#pragma managed` directive to mark the caller as n
416416
WinRT APIs that are released for experimentation and feedback will be decorated with `Windows.Foundation.Metadata.ExperimentalAttribute`. In Update Version 15.3, the compiler will produce warning C4698 when it encounters the attribute. A few APIs in previous versions of the Windows SDK have already been decorated with the attribute, and calls to these APIs will start triggering this compiler warning. Newer Windows SDKs will have the attribute removed from all shipped types, but if you are using an older SDK, you'll need to suppress these warnings for all calls to shipped types.
417417
The following code produces warning C4698: "'Windows::Storage::IApplicationDataStatics2::GetForUserAsync' is for evaluation purposes only and is subject to change or removal in future updates":
418418
```cpp
419-
Windows::Storage::IApplicationDataStatics2::GetForUserAsync()
419+
Windows::Storage::IApplicationDataStatics2::GetForUserAsync() //C4698
420420
```
421421

422422
To disable the warning, add a #pragma:
@@ -436,7 +436,7 @@ Update Version 15.3 produces an error when it encounters an out-of-line definiti
436436
struct S {};
437437

438438
template <typename T>
439-
void S::f(T t) {}
439+
void S::f(T t) {} //C2039: 'f': is not a member of 'S'
440440
```
441441
442442
To fix the error, add a declaration to the class:
@@ -461,7 +461,7 @@ Update Version 15.3 produces an error when you attempt to convert a type to a ba
461461
#include <memory>
462462

463463
class B { };
464-
class D : B { }; // should be public B { };
464+
class D : B { }; // C2243. should be public B { };
465465

466466
void f()
467467
{
@@ -479,7 +479,7 @@ struct A {
479479
};
480480
481481
template <typename T>
482-
T A<T>::f(T t, bool b = false)
482+
T A<T>::f(T t, bool b = false) // C5034
483483
{
484484
...
485485
}
@@ -529,14 +529,15 @@ In Update Version 15.3, the compiler no longer ignores attributes if __declspec(
529529
530530
```cpp
531531
532-
__declspec(noinline) extern "C" HRESULT __stdcall
532+
__declspec(noinline) extern "C" HRESULT __stdcall //C4768
533533
```
534534

535535
To fix the warning, put extern "C" first:
536536

537537
```cpp
538538
extern "C" __declspec(noinline) HRESULT __stdcall
539539
```
540+
This warning is off-by-default and only impacts code compiled with `/Wall /WX`.
540541
541542
### decltype and calls to deleted destructors
542543
In previous versions of Visual Studio, the compiler did not detect when a call to a deleted destructor occurred in the context of the expression associated with 'decltype'. In Update Version 15.3, the following code produces "error C2280: 'A<T>::~A(void)': attempting to reference a deleted function":
@@ -563,7 +564,7 @@ void h()
563564
Visual Studio 2017 RTW release had a regression in which the C++ compiler would not issue a diagnostic if a 'const' variable was not initialized. This regression has been fixed in Visual Studio 2017 Update 1. The following code now produces "warning C4132: 'Value': const object should be initialized":
564565

565566
```cpp
566-
const int Value;
567+
const int Value; //C4132
567568
```
568569
To fix the error, assign a value to `Value`.
569570

@@ -586,5 +587,107 @@ To remove the warnings, simply comment-out or remove the empty declarations. In
586587
The warning is excluded under /Wv:18 and is on by default under warning level W2.
587588
588589
590+
### std::is_convertible for array types
591+
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:
592+
593+
```cpp
594+
#include <type_traits>
595+
596+
using Array = char[1];
597+
598+
static_assert(std::is_convertible<Array, Array>::value);
599+
static_assert((std::is_convertible<const Array, const Array>::value), "");
600+
static_assert((std::is_convertible<Array&, Array>::value), "");
601+
static_assert((std::is_convertible<Array, Array&>::value), "");
602+
```
603+
604+
**std::is_convertible<From, To>** is calculated by checking to see if an imaginary function definition is well formed:
605+
```cpp
606+
To test() { return std::declval<From>(); }
607+
```
608+
609+
### Private destructors and std::is_constructible
610+
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:
611+
612+
```cpp
613+
#include <type_traits>
614+
615+
class PrivateDtor {
616+
PrivateDtor(int) { }
617+
private:
618+
~PrivateDtor() { }
619+
};
620+
621+
// This assertion used to succeed. It now correctly fails.
622+
static_assert(std::is_constructible<PrivateDtor, int>::value);
623+
```
624+
625+
Private destructors cause a type to be non-constructible. **std::is_constructible<T, Args…>** is calculated as if the following declaration were written:
626+
```cpp
627+
T obj(std::declval<Args>()…)
628+
```
629+
This call implies a destructor call.
630+
631+
### C2668: Ambiguous overload resolution
632+
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:
633+
634+
```cpp
635+
namespace N {
636+
template<class T>
637+
void f(T&, T&);
638+
639+
template<class T>
640+
void f();
641+
}
642+
643+
template<class T>
644+
void f(T&, T&);
645+
646+
struct S {};
647+
void f()
648+
{
649+
using N::f;
650+
651+
S s1, s2;
652+
f(s1, s2); // C2668
653+
}
654+
```
655+
To fix the code, remove the using N::f statement if you intended to call ::f().
656+
657+
### C2660: local function declarations and argument dependent lookup
658+
Local function declarations hide the function declaration in the enclosing scope and disable argument dependent lookup.
659+
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:
660+
661+
```cpp
662+
struct S {};
663+
void f(S, int);
664+
665+
void g()
666+
{
667+
void f(S); // C2660 'f': function does not take 2 arguments:
668+
// or void f(S, int);
669+
S s;
670+
f(s, 0);
671+
}
672+
```
673+
674+
To fix the problem, either change the **f(S)** signature or remove it.
675+
676+
### C5038: order of initialization in initializer lists
677+
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 (with /Wall or /WX) raises warning C5038: data member 'A::y' will be initialized after data member 'A::x':
678+
679+
```cpp
680+
struct A
681+
{
682+
A(int a) : y(a), x(y) {} // Initialized in reverse, y reused
683+
int x;
684+
int y;
685+
};
686+
687+
```
688+
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.
689+
690+
Note that the warning is off-by-default and only affects code compiled with /Wall or /WX.
691+
589692
## See Also
590693
[Visual C++ Language Conformance](visual-cpp-language-conformance.md)

docs/porting/visual-cpp-what-s-new-2003-through-2015.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,7 @@ In Visual C++ 2015 and later, ongoing improvements to compiler conformance can s
13831383
warning C4467: Usage of ATL attributes is deprecated
13841384
```
13851385
1386-
If you want to continue using attributed ATL code until support is removed from the compiler, you can disable this warning by passing the `/Wv:18` or `/wd:4467` command line arguments to the compiler, or by adding `#pragma warning(disable:4467)` in your source code.
1386+
If you want to continue using attributed ATL code until support is removed from the compiler, you can disable this warning by passing the `/Wv:18` or `/wd4467` command line arguments to the compiler, or by adding `#pragma warning(disable:4467)` in your source code.
13871387
13881388
Example 1 (before)
13891389

0 commit comments

Comments
 (0)