What’s New
We’ve been busy implementing C++20 features in MSVC’s compiler and Standard Library, and migrating the latter to microsoft/STL on GitHub – in fact, we’ve been so busy that we haven’t posted a C++ toolset changelog since the VS 2019 16.0 toolset changelog. So, here are the compiler features and STL features/fixes that have shipped for production use in the last year.
As a reminder, the /std:c++17 and /std:c++latest compiler options are necessary to use C++17 and C++20 features.
VS 2019 16.1
New features (all thanks to our intern Paolo Torres):
- Implemented P0318R1 “unwrap_reference, unwrap_ref_decay”.
- Implemented P0457R2 “starts_with()/ends_with() For basic_string/basic_string_view”.
- Implemented P0458R2 “contains() For Ordered And Unordered Associative Containers”.
- Implemented P0646R1 “list/forward_list remove()/remove_if()/unique() Return size_type”.
- Implemented P0769R2 “shift_left(), shift_right()”.
- Implemented P0887R1 “type_identity”.
New language features:
- Implemented P0329R4 “Designated initialization”.
- Implemented P0846R0 “ADL and Function Templates that are not Visible”.
Correctness fixes:
- Fixed a regression in VS 2019 16.0 where the bucket count for unordered associative containers might have become higher than intended when using the allocator-extended move constructor with unequal allocators.
- Removed a not-present-in-standard polar function in <complex> that prevented compiling polar<float>(1.0, 2.0).
- Implemented the resolution of LWG-3025, which fixes the deduction guides of map, multimap, unordered_map, and unordered_multimap to enable deduction from e.g. {pair{1, 2}, {3, 4}}.
- Implemented the resolution of LWG-3012, which requires the argument to std::atomic to be copy constructible, move constructible, copy assignable, and move assignable in addition to the previous trivially copyable requirement.
- Removed non-standard std::identity to clear the way for the new standard std::identity. (Thanks to our intern, Paolo Torres!)
- Rewrote <atomic> to improve throughput and codegen – especially for debug compiles – and fixed a bug in constexpr construction of atomic<T*> under Clang.
Performance and throughput fixes:
- Removed several internal “convenience” functions previously used to implement STL features that had poor debug codegen interaction with per-function-overhead options like /RTC1 and /JMC.
- Changed complex to call std::hypot instead of a slightly different library implementation, to engage compiler optimizations for hypot by Vivian An in the optimizer under /fp:fast.
- Fixed vector<bool>::reference’s swap function to be a hidden friend, improving compiler diagnostics when swapping an unrelated unswappable type.
- Fixed several places where the associative containers were using iterator-debugging-enabled iterators internally.
- Optimized the unordered associative container rehash operation by removing self-recursion and try regions.
- Improved throughput of <type_traits> by defining class templates in terms of variable templates when possible and drastically simplifying make_signed_t and make_unsigned_t.
Other improvements:
- The Standard requires implementations to support a certain set of facet specializations. MSVC’s STL permitted non-Standard facet specializations to be used, with often-undesirable consequences. In this release, we implemented an off-by-default mode to enforce that only Standard facet specializations are used, emitting a static_assert for non-Standard usage. Compiling with /D_ENFORCE_FACET_SPECIALIZATIONS=1 will request this mode.
VS 2019 16.2
New features:
- Implemented P0020R6 atomic<float>, atomic<double>, and atomic<long double>. These are always lock-free on all of our supported platforms.
- Implemented relatively fast layout-preserving range checks under a new macro, _CONTAINER_DEBUG_LEVEL, which complements _ITERATOR_DEBUG_LEVEL. We expect this to replace any remaining use cases for _ITERATOR_DEBUG_LEVEL == 1.
- Implemented P0428R6 “Library Support For char8_t” for non-Clang (Clang didn’t know how to mangle char8_t in the MS ABI until Clang 8.0.1).
- Implemented P0754R2 “<version>”.
- Implemented P0463R1 “endian”. (Thanks to our intern, Paolo Torres!)
- Implemented P0600R1 “[[nodiscard]] For The STL”. (Paolo)
- Implemented P0653R2 “to_address()”. (Paolo)
- Implemented P0771R1 “noexcept For std::function’s Move Constructor”. (Paolo)
- Implemented more floating-point <charconv> machinery. Fixed/scientific precision to_chars() is now available, powered by the Ryu Printf algorithm invented and implemented by Ulf Adams.
New language features:
- Implemented P0409R2 “Allow lambda capture [=, this]”.
- Implemented P0428R2 “Familiar template syntax for generic lambdas”.
- Implemented P0482R6 “char8_t: A type for UTF-8 characters and strings”.
- Implemented P0624R2 “Default constructible and assignable stateless lambdas”.
- Implemented P0780R2 “Allow pack expansion in lambda init-capture”.
- Implemented P0806R2 “Deprecate implicit capture of this via [=]”.
- Implemented P1120R0 “Consistency improvements for <=> and other comparison operators”.
- Implemented P1185R2 “<=> != ==”.
Correctness fixes:
- Fixed basic_string to provide the strong exception safety guarantee on copy assignment with unequal propagate_on_container_copy_assignment allocators.
- Fixed _ITERATOR_DEBUG_LEVEL == 1 to no longer do iterator ownership assertions for node-based containers forward_list, list, set, map, multiset, multimap, unordered_set, unordered_map, unordered_multiset, or unordered_multimap. Conditions were discovered where these assertions rejected valid programs in the presence of splices, merges, or usage of C++17 node_handle.
- Fixed list’s remove_if algorithm to tolerate container self-references as an extension permitted but not required by the standard.
- Fixed forward_list::erase_after’s handling of double-exclusive ranges to never cause the container to become corrupted. Edge cases in this handling were found by libcxx’s test suite.
- Fixed multiset and multimap to use the supplied hint to control relative element insertion order in the range of equivalent elements.
- Fixed <filesystem> to interpret the Win32 error code ERROR_INVALID_NAME as a “file not found” error rather than a fatal I/O error for the purposes of status().
- Fixed istream::sentry to not set badbit upon encountering end-of-file when exceptions() has eofbit set.
- Fixed istream::sync() to tolerate streambufs with throwing pubsync().
- Defended against macroization of new C++20 keywords in <xkeycheck.h>.
- Fixed a conflict between mbctype.h and <charconv>. mbctype.h macroizes _M2, so <charconv> now avoids using that as an identifier.
- Fixed deque iterator orphaning, which was causing crashes in debug mode.
- Fixed from_chars() bugs affecting certain corner cases with subnormals.
- Changed from_chars() behavior for overflow/underflow to align with strtod() behavior. (Note that this is tracked by LWG-3081 with a different proposed resolution.)
Performance and throughput fixes:
- Applied if-constexpr to even more places, including <memory>, <functional>, and the allocator-range algorithms used to implement deque, string, and vector.
- Fixed tree-based associative containers set, map, multiset, and multimap to always use the hint parameter if supplied.
- Fixed tree-based associative containers set, map, multiset, and multimap to have reduced code size because the same binary search operation now powers both insertion operations like insert or emplace, as well as plain lookup functions like lower_bound or find. Previously this was duplicated in a manner impossible for the optimizer to merge.
- Removed more try regions from <memory>.
- Optimized associative containers map, set, unordered_map, and unordered_set emplacement to avoid allocating nodes when inserting duplicate keys if the container is passed an instance of the key directly.
- Fixed forward_list::resize to avoid a redundant traversal of the forward_list to calculate the size.
- Reduced forward_list::insert_after’s iterator debugging costs.
- In <charconv>, fixed shortest to_chars() is even faster, optimized by Ryu Printf.
Other improvements:
- Increased the STL’s required version of Clang to 8.0.0.
VS 2019 16.3
New features:
- Implemented P0898R3 “Standard Library Concepts”, which adds the <concepts> header.
- Implemented P0487R1 “Fixing operator>>(basic_istream&, CharT*)”.
- Implemented P0616R0 “Using move() In <numeric>”.
- Implemented P0758R1 “is_nothrow_convertible”.
- Implemented P0919R3 “Heterogeneous Lookup For Unordered Containers”.
- Added [[nodiscard]] attributes to functions with _Check_return_ SAL annotations, which we had skipped in earlier [[nodiscard]] work due to a perception of redundancy.
- Activated STL [[nodiscard]] attributes in C++14 mode when the compiler supports the attribute, which Clang and the IntelliSense compiler do. (MSVC supported [[nodiscard]] in C++14 mode in VS 2019 16.4.) (Did we mention how fond we are of [[nodiscard]]?)
- Added a new header <__msvc_all_public_headers.hpp> to make it easy for people developing tools to ensure they work with all the standard library headers, and need not edit hard-coded lists over time.
New language features:
- Implemented P0734R0 “C++ extensions for Concepts”.
- Implemented P0857R0 “functionality gaps in constraints”.
- Implemented P1084R2 “Today’s return-type-requirements are insufficient”.
Correctness fixes:
- Implemented the is_trivial/is_trivial_v type trait in terms of is_constructible and is_trivially_copyable to work around bugs in MSVC and Clang’s __is_trivial intrinsics.
- Detected more non-compiler tools (Qt’s MOC and Windows’ midl, in addition to pre-existing detection for Windows’ resource compiler) that sometimes process C++ header files, and used the preprocessor to hide the contents of STL headers from them to avoid breakage when the STL uses newer language constructs that such tools don’t understand. (This is a best-effort attempt; ideally folks would not point such tools at STL headers in the first place.)
- Implemented comparison operations for stack and queue in terms of the corresponding operations on the adapted container instead of implementing all in terms of == and < on the adapted container.
- Fixed a bug in pmr::monotonic_resource::release that resulted in use of freed memory on subsequent allocations from the monotonic_resource.
- The STL now uses allocator::construct for container user-supplied types only, so allocators that default-initialize rather than value-initialize no longer break the containers.
- The STL now doesn’t create temporary values on the stack without going through allocator construct for containers.
- Defended against more off-by-default warnings requested by customers, such as C4582, C4583, C4587, C4588, and C4800.
- current_exception() and current_exceptions() now return correct values in terminate handlers.
- Implemented LWG-2996 “Missing rvalue overloads for shared_ptr operations”.
- Implemented LWG-3038 “polymorphic_allocator::allocate should not allow integer overflow to create vulnerabilities”.
- Implemented LWG-3074 “Non-member functions for valarray should only deduce from the valarray”.
- Implemented LWG-3130 “[input.output] needs many addressof”.
- Implemented LWG-3131 “addressof all the things”.
- Simplified is_void_v, is_integral_v, and is_floating_point_v. Previously, we were explicitly specializing non-inline variable templates in C++14 mode, which is technically forbidden by the Standard and was causing headaches for Clang.
Performance and throughput fixes:
- Use the __is_same intrinsic to implement the is_same/is_same_v type trait on Clang.
- Node-based containers will reuse nodes more often when performing bulk operations rather than deallocating and reallocating everything. For example, given a list L containing C elements, L.assign(N, T) now deallocates only the unused C – N elements or allocates only the newly needed N – C elements, rather than freeing all C elements followed by allocating all N elements.
Other improvements:
- <filesystem> no longer includes <experimental/filesystem>.
- <experimental/filesystem> now emits a warning/error: “The <experimental/filesystem> header providing std::experimental::filesystem is deprecated by Microsoft and will be REMOVED. It is superseded by the C++17 <filesystem> header providing std::filesystem. You can define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING to acknowledge that you have received this warning.”
- Deleted the non-Standard <allocators>, <stdexcpt.h>, and <typeinfo.h> headers.
- Removed unnecessary “inline” keywords in the STL.
- Improved the STL’s /Wall cleanliness. Note that this is a work in progress tracked by microsoft/STL#186.
- Eliminated all C casts in the STL’s headers.
- Strengthened noexcept for various functions.
VS 2019 16.4
New features:
- Increased the STL’s required version of Clang to 8.0.1. This notably enables STL char8_t support with Clang, whose previous versions didn’t know how to mangle char8_t in the MS ABI.
- Implemented P1754R1 “Rename Concepts To standard_case”.
- Implemented parts of P0896R4 “<ranges>”:
- Changes to iterator_traits
- Addition of the iterator and range concepts
- ranges::iter_move and ranges::iter_swap customization points
- Range access customization points (normal/const/reverse/const-reverse variations of ranges::begin and ranges::end, ranges::size, ranges::empty, ranges::data, and ranges::cdata)
- The associated type aliases: ranges::iterator_t, ranges::sentinel_t, ranges::range_value_t, ranges::range_reference_t, ranges::range_difference_t, and ranges::range_rvalue_reference_t
- Modifications necessary for array, basic_string, basic_string_view, valarray, and vector to model the contiguous_range concept
- Activated STL [[nodiscard]] attributes in C++14 mode for MSVC.
- Implemented general precision to_chars(), completing C++17 <charconv>.
New language features:
- Implemented P0892R2 “explicit(bool)”.
- Implemented P1091R3 “Extending structured bindings to be more like variable declarations”.
- Implemented P1099R5 “Using Enum”.
- Implemented P1186R3 “When do you actually use <=>?”.
- Implemented P1630R1 “Spaceship needs a tune-up”.
Correctness fixes:
- Explicitly specified the underlying types of some enumeration types in <regex> that use bitwise operations to avoid storing an unrepresentable value (which is formally undefined behavior, as noted by Clang’s UBSAN).
- Implemented LWG-3196 “std::optional<T> is ill-formed if T is an array” (it was already ill-formed, but now there is a friendly static_assert message). Slightly improved throughput by simplifying the metaprogramming for optional<T>’s comparisons with T and by using “if constexpr” instead of tag dispatch in optional::swap.
- Applied a user-supplied work around for an IntelliSense bug in common_reference.
- std::filesystem::directory_entry no longer claims nonexistent files are regular files.
- std::filesystem::directory_iterator(“”) no longer iterates over current_path().
- std::filesystem::recursive_directory_iterator no longer triggers infinite loops when passed paths containing embedded nulls.
- Fixed an edge case in iterator debugging support during list::splice where the container size could be updated incorrectly.
- Improved floating-point <charconv> handling of NaN.
Performance and throughput fixes:
- Reduced the amount of contents included by <compare>.
- Improved list and forward_list’s member algorithms to not need distance/advance calls which were inefficient given that they are non-random-access ranges.
- Partially implemented LWG-2550 “unordered containers’ clear() should be O(number of elements)” as far as our current ABI allows – this speeds up unordered containers with a large number of buckets but few elements. We can only do this if the hash function is noexcept because erasing an element when not walking each bucket requires evaluating the hash function.
- Strengthened noexcept on several container functions.
- atomic<8 bytes> is now implemented with an ordinary load on x86 rather than cmpxchg8b.
- Improved throughput by using conditional explicit in pair/tuple/optional for MSVC and the IntelliSense compiler.
Other improvements:
- Removed the _HAS_SPECIAL_MATH “escape hatch” macro which suppressed definition of the C++17 mathematical special functions in <cmath> when defined to 0.
VS 2019 16.5
Please see https://github.com/microsoft/STL/wiki/Changelog for release notes for the STL in all future Visual Studio releases.
New language features:
- Implemented P0306R4 “Comma omission and comma deletion”.
- Implemented P1042R1 “__VA_OPT_wording clarifications”.
- Implemented P0595R2 “std::is_constant_evaluated()”.
- Implemented P0614R1 “Range-based for statements with initializer”.
- Implemented P0683R1 “Default member initializers for bit-fields”.
- Implemented P1002R1 “Try-catch blocks in constexpr functions”.
- Implemented P1161R3 “Deprecate uses of the comma operator in subscripting expressions”.
- Implemented P1301R4 “[[nodiscard(“should have a reason”)]]”.
- Implemented P1946R0 “Allowing defaulting comparisons by value”.
- Implemented P1703R1 “Recognizing Header Unit Imports Requires Full Preprocessing”.
VS 2019 16.6
Please see https://github.com/microsoft/STL/wiki/Changelog for release notes for the STL in all future Visual Studio releases.
New language features and national body comment resolutions:
- Implemented P0692R1 “Access Checking on Specializations”.
- Implemented P0732R2 “Class Types in Non-Type Template Parameters”.
- Implemented P1139R2 “Address wording issues related to ISO 10646”.
- Implemented P1907R1 “Inconsistencies with non-type template parameters”.
- Implemented P0479R5 “likely and unlikely attributes”.
- Implemented US 053 “Mandate the return type for return_void and return_value to be void”
- Implemented US 065 “Apply Coroutines issue 24 from P0664R8”
More Information
For Visual Studio changes (beyond the C++ toolset) and download links, see the VS Release Notes and VS Preview Release Notes. You can report bugs through Developer Community, and you can also report STL bugs via microsoft/STL GitHub issues.
I know that this is unrelated but I don’t know the proper place to ask this question… May I ask when (or in which version) are you planning to implement full C++20 coroutine support (not the one with “/await”)? It seems that C++20 coroutine will be partially implemented in 16.8 but without the symmetric transfer part. Thanks!
Our compiler front-end dev Jonathan Emmett has contributed the Standard <coroutine> header, including noop_coroutine implemented by our compiler front-end intern Ayesha Gagguturi, for 16.8 (see https://github.com/microsoft/STL/blob/87dc1d3383a052216822fab1a37c8fe2794b0cdb/stl/inc/coroutine ). As you mentioned, symmetric transfer is the last remaining part – our compiler back-end dev Victor Tong has been working on that. We can’t promise anything yet, but it looks like it should be possible for symmetric transfer to be completed for 16.8 Preview 3 and the library feature-test macro updated accordingly; there is one known bug that will need to be fixed in Preview 4. If we encounter unexpected issues in the next few days this may change, hence the lack of guarantees.
Thank you for your nice works!
Do you have any detailed plan to implement P1141R2 (Yet another approach for constrained declarations) ?
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html
The MSVC conformance table says “Partial” ( https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=vs-2019 )
but I could not find any noticeable implementation so far.
vc: https://godbolt.org/z/Q9pU4c
clang: https://godbolt.org/z/5fYVqx
Hi,
As STL explained, the partial state is for the wording in P1141R2 which is related to concept (it amends the syntax for the constrained non-type template argument).
The 16.7 compiler implements the placeholder-type-specifier in P1141R2 and we plan to implement the abbreviated function template in 16.8.
I’ve asked the compiler frontend devs to comment about this too; I do know that the feature is marked as Partial because we’ve implemented P1141R2’s patches to the concepts wording, but not the actual feature that it adds. Perhaps this was confusing; if so, I am to blame 🙂 (This was back when I attempted to keep track of every Core Language feature’s status in addition to all STL features; I maintained an Excel spreadsheet that was then used as a basis for that Microsoft Docs table.)
Noticed a lot of awesome ranges stuff appearing, yay Casey, any chance this will be done for 16.8 or is this later?
Related: https://devblogs.microsoft.com/cppblog/initial-support-for-c20-ranges/. Yes, we’re working on getting Ranges complete for 16.8.
Casey (working with our intern Ahana) is indeed targeting Ranges completion for 16.8; I don’t think we can guarantee this yet, but that’s the goal, and there are a ton of PRs going through review on GitHub. Casey will also be publishing a blog post about the Ranges work.
Great work! Very impressed with how you have been keeping up with a fast-moving standards body.
Thanks! Yeah, as WG21 has added new features at an accelerating pace, both the compiler and libraries teams have had to dramatically change to keep up (team size, engineering systems, etc.). And over the weekend, I finished converting our STL Status Chart from Excel to Chart.js, so you can more easily see how features are being voted in and implemented for the STL; see the purple line at https://microsoft.github.io/STL/ .
Great to hear all the progress! Lots of good changes. I knew there were fixes going into every release but it’d be nice to see this information in the release notes. Usually the VS notes are mostly full of non-C++ changes.
Is there any update on when the experimental preprocessor, experimental lambda, or experimental include features will be out of ‘experimental’ status? I know I wanted to use the new preprocessor but was blocked by the WinSDK not being moved over yet.
I’ve asked compiler frontend devs to provide more detailed info; according to my limited understanding, the experimental preprocessor is becoming officially supported as /Zc:preprocessor due to Elnar’s great work in the frontend (and my coworker Charlie added test coverage for this to the STL). The new lambda processor is being gradually enabled as JonCaves has carefully ironed out the remaining compatibility issues (right now I believe it’s implied by /std:c++latest only, but my info could be incorrect/outdated). I believe that there have been no recent changes to the “external warnings” feature.
We also encountered those WinSDK compatibility issues (for which we have workarounds in the STL’s test coverage); the last I heard, these have been reported to the WinSDK team, but there is no ETA for a fix yet.
There will be a blog on this soon with details, explaining which WinSDK preview will have the necessary backward compatible changes. Please stay tuned.
Is there a place where i can subscribe to see the progress of c++20 modules implementation?
I can’t find where that information
The Visual C++ team has been making good progress on C++20 Modules. We will publish a blog post detailing newly implemented functionalities in the near future (no specific date yet), on the MSVC toolset, the IDE integration (IntelliSense), project and build integration, linker support for module strong ownership, and more.
I’ve asked the compiler frontend team to comment about the current status of modules; on the library side we’ve been working towards completing the “standard library header units” feature; my coworker Steve fixed a conflicting definition of SIZE_MAX in the VCRuntime headers, and when that fix ships in a public Preview, we should be able to add test coverage verifying that all Standard Library headers are importable. We’ve also worked on internal test coverage (I reduced a few compiler bugs that our frontend dev Cameron fixed).