{"id":24086,"date":"2019-04-19T15:46:23","date_gmt":"2019-04-19T15:46:23","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=24086"},"modified":"2019-04-22T15:14:19","modified_gmt":"2019-04-22T15:14:19","slug":"cpp17-20-features-and-fixes-in-vs-2019","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/cpp17-20-features-and-fixes-in-vs-2019\/","title":{"rendered":"C++17\/20 Features and Fixes in Visual Studio 2019"},"content":{"rendered":"<p>Visual Studio 2019 version 16.0 is <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fvisualstudio.microsoft.com%2Fdownloads%2F&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325795031&amp;sdata=kmdIA%2Fv08kw180ANE6zao0CywUCpu5AKx5kyyg2tXFY%3D&amp;reserved=0\">now available<\/a> and is <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fdevblogs.microsoft.com%2Fcppblog%2Fcpp-binary-compatibility-and-pain-free-upgrades-to-visual-studio-2019%2F&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325795031&amp;sdata=I2ik1ImRKY2aLQSzcaBKQtdOVxXhK7NbGSCyGL6zfb4%3D&amp;reserved=0\">binary compatible<\/a> with VS 2015\/2017. In this first release of VS 2019, we&#8217;ve implemented more compiler and library features from the C++20 Working Paper, implemented more <code>&lt;charconv&gt;<\/code> overloads (C++17&#8217;s &#8220;final boss&#8221;), and fixed many correctness, performance, and throughput issues. Here&#8217;s a list of the C++17\/20 compiler\/library feature work and the library fixes. (As usual, many compiler bugs were also fixed, but they aren&#8217;t listed here; compiler fixes tend to be specific to certain arcane code patterns. We recently blogged about <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fdevblogs.microsoft.com%2Fcppblog%2Fgame-performance-and-compilation-time-improvements-in-visual-studio-2019%2F&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325805031&amp;sdata=kokDZblXMBvwxtI48cTcF4vH70UC%2Fb3qTWUKOjEW4KA%3D&amp;reserved=0\">compiler optimization and build throughput improvements in VS 2019<\/a>, and we maintain a documentation page about <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fcpp%2Foverview%2Fcpp-conformance-improvements%3Fview%3Dvs-2019&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325805031&amp;sdata=dfstu7mS5uuxPHbqRxRbGyu09wF%2FmEQNpaHFW3M%2BTow%3D&amp;reserved=0\">compiler conformance improvements in VS 2019<\/a>.)<\/p>\n<p><strong>New Features:<\/strong><\/p>\n<ul>\n<li>Implemented <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2FP1164&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325815034&amp;sdata=01joDu9aJZQruWpxeBIAqijfN%2BCLzzuAuTWzNBx%2F920%3D&amp;reserved=0\">P1164<\/a> from C++20 unconditionally. This changes <code>std::create_directory<\/code> to check whether the target was already a directory on failure. Previously, all <code>ERROR_ALREADY_EXISTS<\/code> type errors were turned into success-but-directory-not-created codes.<\/li>\n<li>The iterator debugging feature has been taught to properly unwrap <code>std::move_iterator<\/code>. For example, <code>std::copy(std::move_iterator&lt;std::vector&lt;int&gt;::iterator&gt;, std::move_iterator&lt;std::vector&lt;int&gt;::iterator&gt;, int*)<\/code> can now engage our <code>memcpy<\/code> fast path.<\/li>\n<li>The standard library&#8217;s macroized keyword enforcement <code>&lt;xkeycheck.h&gt;<\/code> was fixed to emit the actual problem keyword detected rather than a generic message, look for C++20 keywords, and avoid tricking IntelliSense into saying random keywords were macros.<\/li>\n<li>We added <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2Flwg2221&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325815034&amp;sdata=wy%2BvCUyXI4sfKN7aFD6N0jK85e7xcjsZ4TNqO9%2FssqA%3D&amp;reserved=0\">LWG 2221<\/a>&#8216;s <code>operator&lt;&lt;(std::ostream, nullptr_t)<\/code> for writing <code>nullptr<\/code>s to streams.<\/li>\n<li>Parallel versions of <code>is_sorted<\/code>, <code>is_sorted_until<\/code>, <code>is_partitioned<\/code>, <code>set_difference<\/code>, <code>set_intersection<\/code>, <code>is_heap<\/code>, and <code>is_heap_until<\/code> were implemented by Miya Natsuhara.<\/li>\n<li><a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2FP0883&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325825042&amp;sdata=Z%2FjG8zpPXGJgvG8AKcrLgh6yy3%2FJ9fvzIxm9MhYbpyM%3D&amp;reserved=0\">P0883<\/a> &#8220;Fixing atomic initialization&#8221;, which changes <code>std::atomic<\/code> to value-initialize the contained <code>T<\/code> rather than default-initializing it, was implemented (also by Miya) when using Clang\/LLVM with our standard library. This is currently disabled for C1XX as a workaround for a bug in constexpr processing.<\/li>\n<li>Implemented the &#8220;spaceship&#8221; three-way comparison operator from <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2FP0515&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325825042&amp;sdata=vTSZF42ygS9ANheNDVxpop0bGc4E7OIptWynBib1U68%3D&amp;reserved=0\">P0515<\/a> &#8220;Consistent comparison&#8221;, with partial support for the C++20 <code>&lt;compare&gt;<\/code> header as specified in <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2FP0768&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325835049&amp;sdata=Lrwyf5a5W%2Bq3YoXTiUx19XvTW0K9PVGb%2FeGuBkIsgtg%3D&amp;reserved=0\">P0768<\/a> (specifically, the comparison category types and <code>common_comparison_category<\/code> type trait, but not the comparison algorithms which are undergoing some redesign in WG21). (Implemented by Cameron DaCamara in the compiler.)<\/li>\n<li>Implemented the new C++20 <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2FP1008&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325835049&amp;sdata=MbJEIGKbjT%2F6%2F99aeKntxl4LUj6VU1BpeudgtveDsoQ%3D&amp;reserved=0\">P1008<\/a> rules for aggregates: a type with a user-declared constructor &#8211; even when defaulted or deleted so as not to be user-provided &#8211; is not an aggregate. (Implemented by Andrew Marino in the compiler.)<\/li>\n<li>Implemented the <code>remove_cvref<\/code> and <code>remove_cvref_t<\/code> type traits from <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2FP0550&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325845065&amp;sdata=ffE6w%2B8CGT06AzHjszrmpuCnhB21yRlgyBKGJHprT6Q%3D&amp;reserved=0\">P0550<\/a>, which are handy for stripping reference-ness and cv-qualification but without decaying functions and arrays to pointers (which <code>std::decay<\/code> and <code>std::decay_t<\/code> do).<\/li>\n<li>C++17 <code>&lt;charconv&gt;<\/code> floating-point <code>to_chars()<\/code> has been improved: shortest <code>chars_format::fixed<\/code> is 60-80% faster (thanks to Ulf Adams at Google for suggesting long division), and shortest\/precision <code>chars_format::hex<\/code> is complete. Further performance improvements for shortest fixed notation have been implemented and will ship in a future VS 2019 update, along with the decimal precision overloads that will complete the <code>&lt;charconv&gt;<\/code> implementation.<\/li>\n<li>C++20 <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2FP0941&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325845065&amp;sdata=PouAJUnC98m5xrJxQYvDta6yrcWVKW8MrPTw4VJCmwU%3D&amp;reserved=0\">P0941<\/a> feature-test macros are now completely supported in the compiler and STL, including <code>__has_cpp_attribute<\/code> implemented by Phil Christensen. As a reminder, the feature-test macros are always active (i.e. defined or not defined, depending on the availability of the feature in question) regardless of the Standard mode option selected, because making them conditional on <code>\/std:c++latest<\/code> would largely defeat their purpose.<\/li>\n<\/ul>\n<p><strong>Correctness Fixes:<\/strong><\/p>\n<ul>\n<li><code>std::allocator&lt;void&gt;<\/code>, <code>std::allocator::size_type<\/code>, and <code>std::allocator::difference_type<\/code> have been un-deprecated.<\/li>\n<li>A spurious <code>static_cast<\/code> not called for by the standard that accidentally suppressed <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fcpp%2Ferror-messages%2Fcompiler-warnings%2Fcompiler-warning-levels-3-and-4-c4244%3Fview%3Dvs-2019&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325855080&amp;sdata=QCYVWmXxwZYnIpEl4UtgYOxlmwNmyzcje2ZWujZsxe4%3D&amp;reserved=0\">C4244 narrowing warnings<\/a> was removed from <code>std::string<\/code>. Attempting to call <code>std::string::string(const wchar_t*, const wchar_t*)<\/code> will now properly emit C4244 &#8220;narrowing a <code>wchar_t<\/code> into a <code>char<\/code>.&#8221;<\/li>\n<li>Fixed <code>std::filesystem::last_write_time<\/code> failing when attempting to change a directory&#8217;s last write time.<\/li>\n<li><code>std::filesystem::directory_entry<\/code>&#8216;s constructor was changed to store a failed result, rather than throwing an exception, when supplied a nonexistent target path.<\/li>\n<li><code>std::filesystem::create_directory<\/code>&#8216;s 2-parameter version was changed to call the 1-parameter version, as the underlying <code>CreateDirectoryExW<\/code> function would perform <code>copy_symlink<\/code> when the <code>existing_p<\/code> was a symlink.<\/li>\n<li><code>std::filesystem::directory_iterator<\/code> no longer fails when encountering a broken symlink.<\/li>\n<li><code>std::filesystem::space now accepts<\/code> relative paths.<\/li>\n<li><code>std::filesystem::path::lexically_relative<\/code> is no longer confused by trailing slashes, reported as <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2Flwg3096&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325855080&amp;sdata=V2MAB17pRv2hYNwB4MunP1nJqpFsguw1iuUfiPFto1k%3D&amp;reserved=0\">LWG 3096<\/a>.<\/li>\n<li>Worked around <code>CreateSymbolicLinkW<\/code> rejecting paths with forward slashes in <code>std::filesystem::create_symlink<\/code>.<\/li>\n<li>Worked around the POSIX deletion mode delete function existing on Windows 10 LTSB 1609 but not actually being capable of deleting files.<\/li>\n<li><code>std::boyer_moore_searcher<\/code> and <code>std::boyer_moore_horspool_searcher<\/code>&#8216;s copy constructors and copy assignment operators now actually copy things.<\/li>\n<li>The parallel algorithms library now properly uses the real <code>WaitOnAddress<\/code> family on Windows 8 and later, rather than always using the Windows 7 and earlier fake versions.<\/li>\n<li><code>std::system_category::message()<\/code> now trims trailing whitespace from the returned message.<\/li>\n<li>Some conditions that would cause <code>std::linear_congruential_engine<\/code> to trigger divide by 0 have been fixed.<\/li>\n<li>The iterator unwrapping machinery we first exposed for programmer-user integration in VS 2017 15.8 (as described in <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fdevblogs.microsoft.com%2Fcppblog%2Fstl-features-and-fixes-in-vs-2017-15-8%2F&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325865084&amp;sdata=2cu6m7vKOAxM%2FODl2Om4xxjjECBnzJu1%2FdGk9XffIZc%3D&amp;reserved=0\">https:\/\/devblogs.microsoft.com\/cppblog\/stl-features-and-fixes-in-vs-2017-15-8\/<\/a> ) no longer unwraps iterators derived from standard library iterators. For example, a user that derives from <code>std::vector&lt;int&gt;::iterator<\/code> and tries to customize behavior now gets their customized behavior when calling standard library algorithms, rather than the behavior of a pointer.<\/li>\n<li>The unordered container reserve function now actually reserves for N elements, as described in <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2Flwg2156&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325865084&amp;sdata=DHuSVZqWRX%2FdrmnshENO1T9%2FecpteRexX6xIN%2FGbakI%3D&amp;reserved=0\">LWG 2156<\/a>.<\/li>\n<li>Many STL internal container functions have been made private for an improved IntelliSense experience. Additional fixes to mark members as private are expected in subsequent releases of <a href=\"https:\/\/visualstudio.microsoft.com\/vs\/features\/cplusplus\/\">MSVC<\/a>.<\/li>\n<li>Times passed to the concurrency library that would overflow (e.g. <code>condition_variable::wait_for(seconds::max())<\/code>) are now properly dealt with instead of causing overflows that changed behavior on a seemingly random 29-day cycle (when uint32_t milliseconds accepted by underlying Win32 APIs overflowed).<\/li>\n<li>Exception safety correctness problems wherein the node-based containers like <code>list<\/code>, <code>map<\/code>, and <code>unordered_map<\/code> would become corrupted were fixed. During a <code>propagate_on_container_copy_assignment<\/code> or <code>propagate_on_container_move_assignment<\/code> reassignment operation, we would free the container&#8217;s sentinel node with the old allocator, do the POCCA\/POCMA assignment over the old allocator, and then try to acquire the sentinel node from the new allocator. If this allocation failed, the container is corrupted and can&#8217;t even be destroyed, as owning a sentinel node is a hard data structure invariant. This was fixed to allocate the new sentinel node from the source container&#8217;s allocator before destroying the existing sentinel node.<\/li>\n<li>The containers were fixed to always copy\/move\/swap allocators according to <code>propagate_on_container_copy_assignment<\/code>, <code>propagate_on_container_move_assignment<\/code>, and <code>propagate_on_container_swap<\/code>, even for allocators declared <code>is_always_equal<\/code>.<\/li>\n<li><code>std::basic_istream::read<\/code> was fixed to not write into parts of the supplied buffer temporarily as part of \\r\\n =&gt; \\n processing. This gives up some of the performance advantage we gained in VS 2017 15.8 for reads larger than 4k in size, but efficiency improvements from avoiding 3 virtual calls per character are still present.<\/li>\n<li><code>std::bitset<\/code>&#8216;s constructor no longer reads the ones and zeroes in reverse order for large bitsets.<\/li>\n<li>When implementing <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2FP0083&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325875092&amp;sdata=J7QWeOYrl8t7Q0bv6gJpWPU%2BSjsvnmko0o3%2Bf%2F4Gsdo%3D&amp;reserved=0\">P0083<\/a> &#8220;Splicing Maps And Sets&#8221;, we managed to overlook the fact that the <code>merge<\/code> and <code>extract<\/code> members of the associative containers should have overloads that accept rvalue containers in addition to the overloads that accept lvalue containers. We&#8217;ve rectified this oversight by implementing the rvalue overloads.<\/li>\n<li>With the advent of the <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fdevblogs.microsoft.com%2Fcppblog%2Fannouncing-jmc-stepping-in-visual-studio%2F&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325875092&amp;sdata=MHOflspepXdG4YooCOTl2pE4C3JY7PBklrHuJktgPvs%3D&amp;reserved=0\">Just My Code stepping<\/a> feature, we no longer need to provide bespoke machinery for <code>std::function<\/code> and <code>std::visit<\/code> to achieve the same effect. Removing that machinery largely has no user-visible effects, except that the compiler will no longer produce diagnostics that indicate issues on line 15732480 or 16707566 of <code>&lt;type_traits&gt;<\/code> or <code>&lt;variant&gt;<\/code>.<\/li>\n<li>The <code>&lt;ctime&gt;<\/code> header now correctly declares <code>timespec<\/code> and <code>timespec_get<\/code> in namespace <code>std<\/code> in addition to declaring them in the global namespace.<\/li>\n<li>We&#8217;ve fixed a regression in <code>pair<\/code>&#8216;s assignment operator introduced when implementing <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fwg21.link%2Flwg2729&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325885099&amp;sdata=GeX9%2Bu8ZryQqvVJcKdWrY3pHNCm7zPYADbKo3wMvbCM%3D&amp;reserved=0\">LWG 2729<\/a> &#8220;Missing SFINAE on <code>std::pair::operator=<\/code>&#8220;; it now correctly accepts types convertible to pair again.<\/li>\n<li>Fixed a minor type traits bug, where add_const_t etc. is supposed to be a non-deduced context (i.e. it needs to be an alias for <code>typename add_const&lt;T&gt;::type<\/code>, not <code>const T<\/code>).<\/li>\n<\/ul>\n<p><strong>Header Inclusion Restructuring:<\/strong><\/p>\n<p>The standard library&#8217;s physical design was substantially overhauled to avoid including headers when they are not necessary. A large number of customers want to use standard library containers but don&#8217;t want to use the iostreams and locales. However, the C++ standard library has a circular dependency among components:<\/p>\n<ul>\n<li>Systems that depend on <code>&lt;locale&gt;<\/code> facets want to use <code>std::string<\/code> as part of their underlying implementations.<\/li>\n<li><code>std::string<\/code> wants a stream insertion operator, which depends on <code>std::ostream<\/code>, which depends on <code>&lt;locale&gt;<\/code>.<\/li>\n<\/ul>\n<ul>\n<li>Historically our standard library worked around this problem by introducing a lower level header <code>&lt;xstring&gt;<\/code>, which defined <code>std::string<\/code>, but none of the other contents of <code>&lt;string&gt;<\/code>. <code>&lt;xstring&gt;<\/code> would be included by both <code>&lt;locale&gt;<\/code> components, and by <code>&lt;string&gt;<\/code>, restoring the directed dependency graph. However, this approach had a number of problems:<\/li>\n<li><code>#include &lt;string&gt;<\/code> needed to drag in all of the iostreams machinery to provide the stream insertion operator, even though most translation units wouldn&#8217;t use the stream insertion operator.<\/li>\n<li>If someone included only <code>&lt;ostream&gt;<\/code> they got <code>std::basic_string<\/code> and <code>std::ostream<\/code>, but they did <em>not<\/em> get <code>std::basic_string<\/code>&#8216;s stream insertion operator, the <code>std::string<\/code> typedef, or the string literals. Customers found this extremely confusing. For example, if one tried to stream insert a <code>std::basic_string<\/code> after including only <code>&lt;ostream&gt;<\/code>, the compiler would print an incredibly long diagnostic saying <code>operator&lt;&lt;<\/code> couldn&#8217;t be found, listing 26 unrelated overloads. Also, attempts to use <code>std::string_literals<\/code>, <code>std::to_string<\/code>, or other <code>&lt;string&gt;<\/code> components, would fail, which is confusing when <code>std::basic_string<\/code> was otherwise available.<\/li>\n<\/ul>\n<p>In VS 2019, we resolve the circular reference completely differently. The stream insertion operator now finds the necessary <code>ostream<\/code> components using argument-dependent lookup, allowing us to provide it in the same place as string. This restores appropriate layering (of <code>std::string<\/code> below <code>&lt;locale&gt;<\/code> components), and makes it possible to use <code>&lt;string&gt;<\/code> without dragging in the entire mass of iostreams machinery.<\/p>\n<p>If you have lots of <code>.cpp<\/code> files that include <code>string<\/code> and do something simple, for example:<\/p>\n<pre class=\"lang:c++ decode:true\" title=\"Example including string\">#include &lt;stdio.h&gt;\r\n#include &lt;string&gt;\r\n\r\nvoid f(const std::string&amp; s) {\r\n  puts(s.c_str());\r\n}<\/pre>\n<p>In VS 2017 15.9 this program takes 244 milliseconds to compile on a 7980XE test machine (average of 5 runs), while in VS 2019 16.0 it takes only 178 milliseconds (or about 73% of the time).<\/p>\n<p>Moreover, seemingly unrelated headers like <code>&lt;vector&gt;<\/code> were pulled into this mess. For example, <code>vector<\/code> wants to throw <code>std::out_of_range<\/code>, which derives from <code>std::runtime_error<\/code>, which has a constructor that takes a <code>std::string<\/code>. We already had out-of-line functions for all throw sites, so the spurious include of <code>&lt;stdexcept&gt;<\/code> in <code>&lt;vector&gt;<\/code> was unnecessary and has been removed. The following program used to take 177 milliseconds to compile in VS 2017 15.9, but now only needs 151 milliseconds (85% of the time):<\/p>\n<pre class=\"lang:c++ decode:true \" title=\"Example including vector\">#include &lt;vector&gt;\r\n\r\nvoid f(std::vector&lt;int&gt;&amp; v) {\r\n  v.push_back(42);\r\n}<\/pre>\n<p>The one downside of this change is that several programs that were getting away with not including the correct headers may need to add <code>#includes<\/code>. If you were saying <code>std::out_of_range<\/code> before, you may need to <code>#include &lt;stdexcept&gt;<\/code>. If you were using a stream insertion operator, you may now need to <code>#include &lt;ostream&gt;<\/code>. This way, only translation units actually using <code>&lt;stdexcept&gt;<\/code> or <code>&lt;ostream&gt;<\/code> components pay the throughput cost to compile them.<\/p>\n<p><strong>Performance and Throughput Improvements:<\/strong><\/p>\n<ul>\n<li><code>if constexpr<\/code> was applied in more places in the standard library for improved throughput and reduced code size in the <code>copy<\/code> family, permutations like <code>reverse<\/code> and <code>rotate<\/code>, and in the parallel algorithms library.<\/li>\n<li>The STL now internally uses <code>if constexpr<\/code> to reduce compile times even in C++14 mode.<\/li>\n<li>The runtime dynamic linking detection for the parallel algorithms library no longer uses an entire page to store the function pointer array, as marking this memory read-only was deemed no longer relevant for security purposes.<\/li>\n<li><code>std::thread<\/code>&#8216;s constructor no longer waits for the thread to start, and no longer inserts so many layers of function calls between the underlying C library <code>_beginthreadex<\/code> and the supplied callable object. Previously <code>std::thread<\/code> put 6 functions between <code>_beginthreadex<\/code> and the supplied callable object, which has been reduced to only 3 (2 of which are just <code>std::invoke<\/code>). This also resolves an obscure timing bug where <code>std::thread<\/code>&#8216;s constructor would hang if the system clock changed at the exact moment a <code>std::thread<\/code> was being created.<\/li>\n<li>Fixed a performance regression in <code>std::hash<\/code> that we introduced when implementing <code>std::hash&lt;std::filesystem::path&gt;<\/code>.<\/li>\n<li>Several places the standard library used to achieve correctness with catch blocks now use destructors instead. This results in better debugger interaction &#8212; exceptions you throw through the standard library in the affected locations will now show up as being thrown from their original throw site, rather than our rethrow. Not all standard library catch blocks have been eliminated; we expect the number of catch blocks to be reduced in subsequent releases of MSVC.<\/li>\n<li>Suboptimal codegen in <code>std::bitset<\/code> caused by a conditional throw inside a <code>noexcept<\/code> function was fixed by factoring out the throwing path.<\/li>\n<li>The <code>std::list<\/code> and <code>std::unordered_meow<\/code> family use non-debugging iterators internally in more places.<\/li>\n<li>Several <code>std::list<\/code> members were changed to reuse list nodes where possible rather than deallocating and reallocating them. For example, given a <code>list&lt;int&gt;<\/code> that already has a size of 3, a call to <code>assign(4, 1729)<\/code> will now overwrite the ints in the first 3 list nodes, and allocate one new list node with the value 1729, rather than deallocating all 3 list nodes and then allocating 4 new list nodes with the value 1729.<\/li>\n<li>All locations the standard library was calling <code>erase(begin(), end())<\/code> were changed to call <code>clear()<\/code> instead.<\/li>\n<li><code>std::vector<\/code> now initializes and erases elements more efficiently in certain cases.<\/li>\n<li><code>&lt;variant&gt;<\/code> has been refactored to make it more optimizer-friendly, resulting in smaller and faster generated code. Most notably, <code>std::visit<\/code> and the inliner have now become good friends.<\/li>\n<li>We&#8217;ve applied clang-format to the STL&#8217;s headers for improved readability. (There were additional manual changes, e.g. adding braces to all control flow.)<\/li>\n<\/ul>\n<p><strong>Reporting Bugs:<\/strong><\/p>\n<p>Please let us know what you think about VS 2019. You can report bugs via the IDE&#8217;s Report A Problem and also via the web, at the <a href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Fdevelopercommunity.visualstudio.com%2Fspaces%2F62%2Findex.html&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7C67737af822834c9adcc508d6bd4a5620%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636904524325885099&amp;sdata=NnC9nd21T5yAzzgfyFo6vqnL5n3Iw7EwUQqEzKyxzD4%3D&amp;reserved=0\">Developer Community&#8217;s C++ tab<\/a>.<\/p>\n<p>Billy O&#8217;Neal, Casey Carter, and Stephan T. Lavavej<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Visual Studio 2019 version 16.0 is now available and is binary compatible with VS 2015\/2017. In this first release of VS 2019, we&#8217;ve implemented more compiler and library features from the C++20 Working Paper, implemented more &lt;charconv&gt; overloads (C++17&#8217;s &#8220;final boss&#8221;), and fixed many correctness, performance, and throughput issues. Here&#8217;s a list of the C++17\/20 [&hellip;]<\/p>\n","protected":false},"author":266,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[270],"tags":[],"class_list":["post-24086","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcement"],"acf":[],"blog_post_summary":"<p>Visual Studio 2019 version 16.0 is now available and is binary compatible with VS 2015\/2017. In this first release of VS 2019, we&#8217;ve implemented more compiler and library features from the C++20 Working Paper, implemented more &lt;charconv&gt; overloads (C++17&#8217;s &#8220;final boss&#8221;), and fixed many correctness, performance, and throughput issues. Here&#8217;s a list of the C++17\/20 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/24086","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/266"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=24086"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/24086\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=24086"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=24086"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=24086"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}