Skip to content

Commit ec7fb11

Browse files
author
Michael Blome
committed
https://review.docs.microsoft.com/en-us/cpp/standard-library/forward-list-functions#swap
upddddnewe enter the commit message for your changes. Lines starting Updates and new content for conformance
1 parent 85ced73 commit ec7fb11

File tree

1 file changed

+347
-0
lines changed

1 file changed

+347
-0
lines changed
Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
---
2+
title: "C++ compiler conformance improvements | Microsoft Docs"
3+
ms.custom: ""
4+
ms.date: "11/16/2016"
5+
ms.prod: "visual-studio-dev15"
6+
ms.reviewer: ""
7+
ms.suite: ""
8+
ms.technology:
9+
- "vs-ide-general"
10+
ms.tgt_pltfrm: ""
11+
ms.topic: "article"
12+
ms.assetid: 8801dbdb-ca0b-491f-9e33-01618bff5ae9
13+
author: "BrianPeek"
14+
ms.author: "brpeek"
15+
manager: "ghogen"
16+
translation.priority.ht:
17+
- "cs-cz"
18+
- "de-de"
19+
- "es-es"
20+
- "fr-fr"
21+
- "it-it"
22+
- "ja-jp"
23+
- "ko-kr"
24+
- "pl-pl"
25+
- "pt-br"
26+
- "ru-ru"
27+
- "tr-tr"
28+
- "zh-cn"
29+
- "zh-tw"
30+
---
31+
32+
# C++ conformance improvements in [!INCLUDE[vs_dev15_md](../misc/includes/vs_dev15_md.md)]
33+
In this release, we've updated the C++ compiler and standard library with enhanced support for C++11 and C++14 features, as well as preliminary support for certain features expected to be in the C++17 standard. With support for generalized constexpr and NSDMI for aggregates, the compiler is complete for features added in the C++14 Standard. Note that the compiler still lacks a few features from the C++11 and C++98 Standards.
34+
35+
## New language features
36+
37+
### Standards version switches
38+
New compiler switches enable you to opt-in to specific versions of the ISO C++ programming language in a project. The switches available in Visual Studio 2017 are /std:c++14 and /std:c++latest. For more information, see [Standards version switches in the compiler](https://blogs.msdn.microsoft.com/vcblog/2016/06/07/standards-version-switches-in-the-compiler). Most of the new draft standard features are guarded by the /std:c++latest switch.
39+
40+
### C++11:
41+
**Expression SFINAE (via more libraries)support in more libraries**
42+
The Visual C++ compiler is now capable continues to improve its support for expression SFINAE, which is required for template argument deduction and substitution where decltype and constexpr expressions may appear as template parameters. For more information, see [Expression SFINAE improvements in VS 2015 Update 3](https://blogs.msdn.microsoft.com/vcblog/2016/06/07/expression-sfinae-improvements-in-vs-2015-update-3).
43+
44+
45+
### C++ 14:
46+
**NSDMI for Aggregates**
47+
An aggregate is an array or a class with no user-provided constructor, no private or protected non-static data members, no base classes, and no virtual functions. Beginning in C++14 aggregates may contain member initializers. For more information, see [Member initializers and aggregates](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3605.html).
48+
49+
**Extended constexpr**
50+
Expressions declared as constexpr are now allowed to contain certain kinds of declarations, if and switch statements, loop statements, and mutation of objects whose lifetime began within the constexpr expression evaluation. Also, there is no longer a requirement that a constexpr non-static member function be implicitly const. For more information, see [Relaxing constraints on constexpr functions](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3652.html).
51+
52+
### C++17 (available with /std:c++latest):
53+
**Terse static_assert** (available with /std:c++latest)
54+
In C++17 the message parameter for static_assert is optional. For more information, see [Extending static_assert, v2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3928.pdf).
55+
56+
**[[fallthrough]] attribute** (available with /std:c++latest)
57+
The [[fallthrough]] attribute can be used in the context of switch statements as a hint to the compiler that the fall-through behavior is intended. This prevents the compiler from issuing warnings in such cases. For more information, see [Wording for [[fallthrough]] attribute](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0188r0.pdf).
58+
59+
**Generalized range-based for loops** (no compiler switch required)
60+
Range-based for loops no longer require that begin() and end() return objects of the same type. This enables end() to return a sentinel object such as used by ranges as defined in the Ranges-V3 proposal. For more information, see [Generalizing the Range-Based For Loop](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html) and the [range-v3 library on GitHub](https://github.com/ericniebler/range-v3).
61+
62+
63+
For the complete list of conformance improvements up through Visual Studio 2015, Update 3, see [Visual C++ What's New 2003 through 2015](https://msdn.microsoft.com/en-us/library/mt723604.aspx).
64+
65+
66+
67+
## Bug fixes
68+
### Copy-list-initialization
69+
Visual Studio 2017 correctly raises compiler errors related to object creation using initializer lists that were not caught in Visual Studio 2015 and could lead to crashes or undefined runtime behavior. In copy-list-initialization, the compiler is required to consider an explicit constructor for overload resolution, but must raise an error if that overload is actually chosen.
70+
The following two examples compile in Visual Studio 2015 but not in Visual Studio 2017.
71+
```cpp
72+
struct A
73+
{
74+
explicit A(int) {}
75+
A(double) {}
76+
};
77+
78+
int main()
79+
{
80+
A a1 = { 1 }; // error C3445: copy-list-initialization of 'A' cannot use an explicit constructor
81+
const A& a2 = { 1 }; // error C2440: 'initializing': cannot convert from 'int' to 'const A &'
82+
83+
}
84+
```
85+
To correct the error, use direct initialization:
86+
```cpp
87+
A a1{ 1 };
88+
const A& a2{ 1 };
89+
```
90+
91+
In Visual Studio 2015, the compiler erroneously treated copy-list-initialization in the same way as regular copy-initialization; it considered only converting constructors for overload resolution. In the following example, Visual Studio 2015 chooses MyInt(23) but Visual Studio 2017 correctly raises the error.
92+
93+
```cpp
94+
// From http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1228
95+
struct MyList {
96+
explicit MyStore(int initialCapacity);
97+
};
98+
99+
struct MyInt {
100+
MyInt(int i);
101+
};
102+
103+
struct Printer {
104+
void operator()(MyStore const& s);
105+
void operator()(MyInt const& i);
106+
};
107+
108+
void f() {
109+
Printer p;
110+
p({ 23 }); // C3066: there are multiple ways that an object of this type can be called with these arguments
111+
}
112+
```
113+
114+
This example is similar to the previous one but raises a different error. It succeeds in Visual Studio 2015 and fails in Visual Studio 2017 with C2668.
115+
116+
```cpp
117+
struct A {
118+
explicit A(int) {}
119+
};
120+
121+
struct B {
122+
B(int) {}
123+
};
124+
125+
void f(const A&) {}
126+
void f(const B&) {}
127+
128+
int main()
129+
{
130+
f({ 1 }); // error C2668: 'f': ambiguous call to overloaded function
131+
}
132+
```
133+
134+
### Deprecated typedefs
135+
Visual Studio 2017 now issues the correct warning for deprecated typedefs that are declared in a class or struct. The following example compiles without warnings in Visual Studio 2015 but produces C4996 in Visual Studio 2017.
136+
137+
```cpp
138+
struct A
139+
{
140+
// also for __declspec(deprecated)
141+
[[deprecated]] typedef int inttype;
142+
};
143+
144+
int main()
145+
{
146+
A::inttype a = 0; // C4996 'A::inttype': was declared deprecated
147+
}
148+
```
149+
150+
### constexpr
151+
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:
152+
153+
```cpp
154+
template<int N>
155+
struct array
156+
{
157+
int size() const { return N; }
158+
};
159+
160+
constexpr bool f(const array<1> &arr)
161+
{
162+
return arr.size() == 10 || arr.size() == 11; // error starting in Visual Studio 2017
163+
}
164+
```
165+
To correct the error, either declare the array::size() function as constexpr or remove the constexpr qualifier from f.
166+
167+
### Class types passed to variadic functions
168+
In Visual Studio 2017, classes or structs that are passed to a variadic function such as printf must be trivially copyable. When passing such objects, the compiler simply makes a bitwise copy and does not call the constructor or destructor.
169+
170+
```cpp
171+
#include <atomic>
172+
#include <memory>
173+
#include <stdio.h>
174+
175+
int main()
176+
{
177+
std::atomic<int> i(0);
178+
printf("%i\n", i); // error C4839: non-standard use of class 'std::atomic<int>'
179+
// as an argument to a variadic function
180+
// note: the constructor and destructor will not be called;
181+
// a bitwise copy of the class will be passed as the argument
182+
// error C2280: 'std::atomic<int>::atomic(const std::atomic<int> &)':
183+
// attempting to reference a deleted function
184+
185+
struct S {
186+
S(int i) : i(i) {}
187+
S(const S& other) : i(other.i) {}
188+
operator int() { return i; }
189+
private:
190+
int i;
191+
} s(0);
192+
printf("%i\n", s); // warning C4840 : non-portable use of class 'main::S'
193+
// as an argument to a variadic function
194+
}
195+
```
196+
To correct the error, you can callC2672 a member function that returns a trivially copyable type,
197+
198+
```cpp
199+
std::atomic<int> i(0);
200+
printf("%i\n", i.load());
201+
```
202+
or else perform a static cast to convert the object before passing it:
203+
```cpp
204+
struct S {/* as before */} s(0);
205+
printf("%i\n", static_cast<int>(s))
206+
```
207+
For strings built and managed using CStringW, the provided ‘operator LPCWSTR()’ should be used to cast a CStringW object to the C pointer expected by the format string.
208+
```cpp
209+
CStringW str1;
210+
CStringW str2;
211+
str1.Format(… , static_cast<LPCWSTR>(str2));
212+
```
213+
214+
### cv-qualifiers in class construction
215+
In Visual Studio 2015, the compiler sometimes incorrectly ignores the cv-qualifier when generating a class object via a constructor call. This can potentially cause a crash or unexpected runtime behavior. The following example compiles in Visual Studio 2015 but raises a compiler error in Visual Studio 2017:
216+
217+
```cpp
218+
struct S
219+
{
220+
S(int);
221+
operator int();
222+
};
223+
224+
int i = (const S)0; // error C2440
225+
```
226+
To correct the error, declare operator int() as const.
227+
228+
### Access checking on qualified names in templates
229+
Previous versions of the compiler did not perform access checking on qualified names in some template contexts. This can interfere with expected SFINAE behavior where the substitution is expected to fail due to the inaccessibility of a name. This could have potentially caused a crash or unexpected behavior at runtime due to the compiler incorrectly calling the wrong overload of the operator. In Visual Studio 2017, a compiler error is raised. The specific error might vary but typically it is "C2672 no matching overloaded function found". The following code compiles in Visual Studio 2015 but raises an error in Visual Studio 2017:
230+
231+
```cpp
232+
#include <type_traits>
233+
234+
template <class T> class S {
235+
typedef typename T type;
236+
};
237+
238+
template <class T, std::enable_if<std::is_integral<typename S<T>::type>::value, T> * = 0>
239+
bool f(T x);
240+
241+
int main()
242+
{
243+
f(10); // C2672: No matching overloaded function found.
244+
}
245+
```
246+
247+
### Missing template argument lists
248+
In Visual Studio 2015 and earlier, the compiler did not diagnose missing template argument lists when the template appeared in a template parameter list (for example as part of a default template argument or a non-type template parameter). This can result in unpredictable behavior, including compiler crashes or unexpected runtime behavior. The following code compiles in Visual Studio 2015 but produces an error in Visual Studio 2017.
249+
250+
```cpp
251+
template <class T> class ListNode;
252+
template <class T> using ListNodeMember = ListNode<T> T::*;
253+
template <class T, ListNodeMember M> class ListHead; // C2955: 'ListNodeMember': use of alias template requires template argument list
254+
255+
// correct: template <class T, ListNodeMember<T> M> class ListHead;
256+
```
257+
258+
### Expression-SFINAE
259+
As part of supporting expression-SFINAE the compiler now parses decltype arguments when the templates are declared rather than instantiated. Consequently, if a non-dependent specialization is found in the decltype argument, it will not be deferred to instantiation-time and will be processed immediately and any resulting errors will be diagnosed at that time.
260+
The following example shows such a compiler error that is raised at the point of declaration:
261+
262+
```cpp
263+
#include <utility>
264+
template <class T, class ReturnT, class... ArgsT> class IsCallable
265+
{
266+
public:
267+
struct BadType {};
268+
template <class U>
269+
static decltype(std::declval<T>()(std::declval<ArgsT>()...)) Test(int); //C2064. Should be declval<U>
270+
template <class U>
271+
static BadType Test(...);
272+
static constexpr bool value = std::is_convertible<decltype(Test<T>(0)), ReturnT>::value;
273+
};
274+
275+
constexpr bool test1 = IsCallable<int(), int>::value;
276+
static_assert(test1, "PASS1");
277+
constexpr bool test2 = !IsCallable<int*, int>::value;
278+
static_assert(test2, "PASS2");
279+
```
280+
281+
### Default initializers for value class members (C++/CLI)
282+
In Visual Studio 2015 and earlier, the compiler permitted (but ignored) a default member initializer for a member of a value class. Default initialization of a value class always zero-initializes the members; a default constructor is not permitted. In Visual Studio 2017, default member initializers raise a compiler error, as shown in this example:
283+
284+
```cpp
285+
value struct V
286+
{
287+
int i = 0; // error C3446: 'V::i': a default member initializer is not allowed for a member of a value class
288+
};
289+
```
290+
291+
### Default Indexers (C++/CLI)
292+
In Visual Studio 2015 and earlier, the compiler in some cases misidentified a default property as a default indexer. It was possible to work around the issue by using the identifier "default" to access the property. The workaround itself became problematic after default was introduced as a keyword in C++11. Therefore, in Visual Studio 2017 the bugs that required the workaround were fixed, and the compiler now raises an error when "default" is used to access the default property for a class.
293+
294+
```cpp
295+
//class1.cs
296+
297+
using System.Reflection;
298+
using System.Runtime.InteropServices;
299+
300+
namespace ClassLibrary1
301+
{
302+
[DefaultMember("Value")]
303+
public class Class1
304+
{
305+
public int Value
306+
{
307+
// using attribute on the return type triggers the compiler bug
308+
[return: MarshalAs(UnmanagedType.I4)]
309+
get;
310+
}
311+
}
312+
[DefaultMember("Value")]
313+
public class Class2
314+
{
315+
public int Value
316+
{
317+
get;
318+
}
319+
}
320+
}
321+
322+
323+
// code.cpp
324+
#using "class1.dll"
325+
326+
void f(ClassLibrary1::Class1 ^r1, ClassLibrary1::Class2 ^r2)
327+
{
328+
r1->Value; // error
329+
r1->default;
330+
r2->Value;
331+
r2->default; // error
332+
}
333+
```
334+
335+
In Visual Studio 2017, you can access both Value properties by their name:
336+
337+
```cpp
338+
#using "class1.dll"
339+
340+
void f(ClassLibrary1::Class1 ^r1, ClassLibrary1::Class2 ^r2)
341+
{
342+
r1->Value;
343+
r2->Value;
344+
}
345+
```
346+
347+

0 commit comments

Comments
 (0)