| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,16 +1,16 @@ | |||
| 1 | 1 | --- | |
| 2 | 2 | title: "C++ compiler conformance improvements | Microsoft Docs" | |
| 3 | 3 | ms.custom: "" | |
| 4 | - ms.date: "11/16/2016" | ||
| 4 | + ms.date: "06/05/2017" | ||
| 5 | 5 | ms.reviewer: "" | |
| 6 | 6 | ms.suite: "" | |
| 7 | 7 | ms.technology: | |
| 8 | 8 | - "vs-ide-general" | |
| 9 | 9 | ms.tgt_pltfrm: "" | |
| 10 | 10 | ms.topic: "article" | |
| 11 | 11 | ms.assetid: 8801dbdb-ca0b-491f-9e33-01618bff5ae9 | |
| 12 | - author: "BrianPeek" | ||
| 13 | - ms.author: "brpeek" | ||
| 12 | + author: "mikeblome" | ||
| 13 | + ms.author: "mblome" | ||
| 14 | 14 | manager: "ghogen" | |
| 15 | 15 | translation.priority.ht: | |
| 16 | 16 | - "cs-cz" | |
@@ -143,7 +143,7 @@ int main() | |||
| 143 | 143 | ``` | |
| 144 | 144 | ||
| 145 | 145 | ### 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): | ||
| 147 | 147 | ||
| 148 | 148 | ```cpp | |
| 149 | 149 | template<int N> | |
@@ -154,7 +154,7 @@ struct array | |||
| 154 | 154 | ||
| 155 | 155 | constexpr bool f(const array<1> &arr) | |
| 156 | 156 | { | |
| 157 | - return arr.size() == 10 || arr.size() == 11; // error starting in Visual Studio 2017 | ||
| 157 | + return arr.size() == 10 || arr.size() == 11; // C3615 | ||
| 158 | 158 | } | |
| 159 | 159 | ``` | |
| 160 | 160 | 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 | |||
| 372 | 372 | struct S; | |
| 373 | 373 | enum E; | |
| 374 | 374 | ||
| 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 | ||
| 377 | 377 | ``` | |
| 378 | 378 | ||
| 379 | 379 | ### 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 | |||
| 416 | 416 | 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. | |
| 417 | 417 | 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": | |
| 418 | 418 | ```cpp | |
| 419 | - Windows::Storage::IApplicationDataStatics2::GetForUserAsync() | ||
| 419 | + Windows::Storage::IApplicationDataStatics2::GetForUserAsync() //C4698 | ||
| 420 | 420 | ``` | |
| 421 | 421 | ||
| 422 | 422 | 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 | |||
| 436 | 436 | struct S {}; | |
| 437 | 437 | ||
| 438 | 438 | template <typename T> | |
| 439 | - void S::f(T t) {} | ||
| 439 | + void S::f(T t) {} //C2039: 'f': is not a member of 'S' | ||
| 440 | 440 | ``` | |
| 441 | 441 | ||
| 442 | 442 | 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 | |||
| 461 | 461 | #include <memory> | |
| 462 | 462 | ||
| 463 | 463 | class B { }; | |
| 464 | - class D : B { }; // should be public B { }; | ||
| 464 | + class D : B { }; // C2243. should be public B { }; | ||
| 465 | 465 | ||
| 466 | 466 | void f() | |
| 467 | 467 | { | |
@@ -479,7 +479,7 @@ struct A { | |||
| 479 | 479 | }; | |
| 480 | 480 | ||
| 481 | 481 | template <typename T> | |
| 482 | - T A<T>::f(T t, bool b = false) | ||
| 482 | + T A<T>::f(T t, bool b = false) // C5034 | ||
| 483 | 483 | { | |
| 484 | 484 | ... | |
| 485 | 485 | } | |
@@ -529,14 +529,15 @@ In Update Version 15.3, the compiler no longer ignores attributes if __declspec( | |||
| 529 | 529 | ||
| 530 | 530 | ```cpp | |
| 531 | 531 | ||
| 532 | - __declspec(noinline) extern "C" HRESULT __stdcall | ||
| 532 | + __declspec(noinline) extern "C" HRESULT __stdcall //C4768 | ||
| 533 | 533 | ``` | |
| 534 | 534 | ||
| 535 | 535 | To fix the warning, put extern "C" first: | |
| 536 | 536 | ||
| 537 | 537 | ```cpp | |
| 538 | 538 | extern "C" __declspec(noinline) HRESULT __stdcall | |
| 539 | 539 | ``` | |
| 540 | + This warning is off-by-default and only impacts code compiled with `/Wall /WX`. | ||
| 540 | 541 | ||
| 541 | 542 | ### decltype and calls to deleted destructors | |
| 542 | 543 | 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() | |||
| 563 | 564 | 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": | |
| 564 | 565 | ||
| 565 | 566 | ```cpp | |
| 566 | - const int Value; | ||
| 567 | + const int Value; //C4132 | ||
| 567 | 568 | ``` | |
| 568 | 569 | To fix the error, assign a value to `Value`. | |
| 569 | 570 | ||
@@ -586,5 +587,107 @@ To remove the warnings, simply comment-out or remove the empty declarations. In | |||
| 586 | 587 | The warning is excluded under /Wv:18 and is on by default under warning level W2. | |
| 587 | 588 | ||
| 588 | 589 | ||
| 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 | + | ||
| 589 | 692 | ## See Also | |
| 590 | 693 | [Visual C++ Language Conformance](visual-cpp-language-conformance.md) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1383,7 +1383,7 @@ In Visual C++ 2015 and later, ongoing improvements to compiler conformance can s | |||
| 1383 | 1383 | warning C4467: Usage of ATL attributes is deprecated | |
| 1384 | 1384 | ``` | |
| 1385 | 1385 | ||
| 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. | ||
| 1387 | 1387 | ||
| 1388 | 1388 | Example 1 (before) | |
| 1389 | 1389 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments