C++17 Progress in VS 2017 15.5 and 15.6

VS 2017 15.5 is now available for production use, and 15.6 Preview 1 is also available. As usual, here are feature tables for the STL and compiler, plus a detailed list of STL improvements. (You can also read our previous changelog for VS 2017 15.3.) Please note that due to our branch structure and merge timing, features and fixes described below as being in VS 2017 15.6 have been checked in and will be available by the time that it’s ready for production use, but 15.6 Preview 1 contains only a subset of those features and fixes.

 

STL Feature Status:

Status

Std

Paper

Title

Notes

missing

C++17

P0067R5

Elementary String Conversions

 

patch

C++17

P0682R1

Repairing Elementary String Conversions

[DR]

missing

C++17

P0030R1

hypot(x, y, z)

 

missing

C++17

P0226R1

Mathematical Special Functions

 

Partial

C++17

P0024R2

Parallel Algorithms

[parallel]

patch

C++17

P0336R1

Renaming Parallel Execution Policies

 

patch

C++17

P0394R4

Parallel Algorithms Should terminate() For Exceptions

 

patch

C++17

P0452R1

Unifying <numeric> Parallel Algorithms

 

patch

C++17

P0467R2

Requiring Forward Iterators In Parallel Algorithms

 

patch

C++17

P0502R0

Parallel Algorithms Should terminate() For Exceptions, Usually

 

patch

C++17

P0518R1

Copying Trivially Copy Constructible Elements In Parallel Algorithms

 

patch

C++17

P0523R1

Relaxing Complexity Requirements Of Parallel Algorithms (General)

 

patch

C++17

P0574R1

Relaxing Complexity Requirements Of Parallel Algorithms (Specific)

 

patch

C++17

P0623R0

Final C++17 Parallel Algorithms Fixes

 

missing

C++17

P0218R1

<filesystem>

 

patch

C++17

P0219R1

Relative Paths For Filesystem

 

patch

C++17

P0317R1

Directory Entry Caching For Filesystem

 

patch

C++17

P0392R0

Supporting string_view In Filesystem Paths

 

patch

C++17

P0430R2

Supporting Non-POSIX Filesystems

 

patch

C++17

P0492R2

Resolving NB Comments For Filesystem

 

VS 2017 15.x

C++20

P0777R1

Avoiding Unnecessary decay

[decay] [14]

VS 2017 15.6

C++17

<memory_resource>

 

VS 2017 15.6

C++17

P0220R1

Library Fundamentals V1

 

VS 2017 15.6

C++17

P0337R0

Deleting polymorphic_allocator Assignment

 

Partial 15.6

C++17

P0426R1

constexpr For char_traits

[char_traits]

Partial 15.6

C++17

P0433R2

Deduction Guides For The STL

[guides]

VS 2017 15.6

C++17

P0739R0

Improving Class Template Argument Deduction For The STL

[DR]

VS 2017 15.5

C++17

P0003R5

Removing Dynamic Exception Specifications

[rem]

VS 2017 15.5

C++17

P0005R4

not_fn()

[depr]

VS 2017 15.5

C++17

P0033R1

Rewording enable_shared_from_this

[14]

VS 2017 15.5

C++17

P0083R3

Splicing Maps And Sets

 

VS 2017 15.5

C++17

P0174R2

Deprecating Vestigial Library Parts

[depr]

VS 2017 15.5

C++17

P0302R1

Removing Allocator Support In std::function

[rem]

VS 2017 15.5

C++17

P0358R1

Fixes For not_fn()

 

VS 2017 15.5

C++17

P0414R2

shared_ptr<T[]>, shared_ptr<T[N]>

[14]

VS 2017 15.5

C++17

P0497R0

Fixing shared_ptr For Arrays

[14]

VS 2017 15.5

C++17

P0508R0

Clarifying insert_return_type

 

VS 2017 15.5

C++17

P0521R0

Deprecating shared_ptr::unique()

[depr]

VS 2017 15.5

C++17

P0607R0

Inline Variables For The STL

 

VS 2017 15.5

C++17

P0618R0

Deprecating <codecvt>

[depr]

VS 2017 15.3

C++17

Boyer-Moore search()

 

VS 2017 15.3

C++17

P0031R0

constexpr For <array> (Again) And <iterator>

 

VS 2017 15.3

C++17

P0040R3

Extending Memory Management Tools

 

VS 2017 15.3

C++17

P0084R2

Emplace Return Type

 

VS 2017 15.3

C++17

P0152R1

atomic::is_always_lock_free

 

VS 2017 15.3

C++17

P0154R1

hardware_destructive_interference_size, etc.

 

VS 2017 15.3

C++17

P0156R2

scoped_lock

 

VS 2017 15.3

C++17

P0253R1

Fixing Searcher Return Types

 

VS 2017 15.3

C++17

P0258R2

has_unique_object_representations

[obj_rep]

VS 2017 15.3

C++17

P0295R0

gcd(), lcm()

 

VS 2017 15.3

C++17

P0298R3

std::byte

[byte]

VS 2017 15.3

C++17

P0403R1

UDLs For <string_view> (“meow”sv, etc.)

 

VS 2017 15.3

C++17

P0418R2

atomic compare_exchange memory_order Requirements

[14]

VS 2017 15.3

C++17

P0435R1

Overhauling common_type

[14]

VS 2017 15.3

C++17

P0505R0

constexpr For <chrono> (Again)

 

VS 2017 15.3

C++17

P0513R0

Poisoning hash

[14]

VS 2017 15.3

C++17

P0516R0

Marking shared_future Copying As noexcept

[14]

VS 2017 15.3

C++17

P0517R0

Constructing future_error From future_errc

[14]

VS 2017 15.3

C++17

P0548R1

Tweaking common_type And duration

[14]

VS 2017 15.3

C++17

P0558R1

Resolving atomic<T> Named Base Class Inconsistencies

[atomic] [14]

VS 2017 15.3

C++17

P0599R1

noexcept hash

[14]

VS 2017 15.3

C++17

P0604R0

invoke_result, is_invocable, is_nothrow_invocable

[depr]

VS 2017

C++17

<algorithm> sample()

 

VS 2017

C++17

<any>

 

VS 2017

C++17

<optional>

 

VS 2017

C++17

<string_view>

 

VS 2017

C++17

<tuple> apply()

 

VS 2017

C++17

P0032R3

Homogeneous Interface For variant/any/optional

 

VS 2017

C++17

P0077R2

is_callable, is_nothrow_callable

 

VS 2017

C++17

P0088R3

<variant>

 

VS 2017

C++17

P0163R0

shared_ptr::weak_type

 

VS 2017

C++17

P0209R2

make_from_tuple()

 

VS 2017

C++17

P0254R2

Integrating string_view And std::string

 

VS 2017

C++17

P0307R2

Making Optional Greater Equal Again

 

VS 2017

C++17

P0393R3

Making Variant Greater Equal

 

VS 2017

C++17

P0504R0

Revisiting in_place_t/in_place_type_t<T>/in_place_index_t<I>

 

VS 2017

C++17

P0510R0

Rejecting variants Of Nothing, Arrays, References, And Incomplete Types

 

VS 2015.3

C++17

P0025R1

clamp()

 

VS 2015.3

C++17

P0185R1

is_swappable, is_nothrow_swappable

 

VS 2015.3

C++17

P0272R1

Non-const basic_string::data()

 

VS 2015.2

C++17

N4387

Improving pair And tuple

[14]

VS 2015.2

C++17

N4508

shared_mutex (Untimed)

[14]

VS 2015.2

C++17

P0004R1

Removing Deprecated Iostreams Aliases

[rem]

VS 2015.2

C++17

P0006R0

Variable Templates For Type Traits (is_same_v, etc.)

[14]

VS 2015.2

C++17

P0007R1

as_const()

[14]

VS 2015.2

C++17

P0013R1

Logical Operator Type Traits (conjunction, etc.)

[14]

VS 2015.2

C++17

P0074R0

owner_less<>

[14]

VS 2015.2

C++17

P0092R1

<chrono> floor(), ceil(), round(), abs()

[14]

VS 2015.2

C++17

P0156R0

Variadic lock_guard

[14]

VS 2015

C++17

N3911

void_t

[14]

VS 2015

C++17

N4089

Safe Conversions In unique_ptr<T[]>

[14]

VS 2015

C++17

N4169

invoke()

[14]

VS 2015

C++17

N4190

Removing auto_ptr, random_shuffle(), And Old <functional> Stuff

[rem]

VS 2015

C++17

N4258

noexcept Cleanups

[14]

VS 2015

C++17

N4259

uncaught_exceptions()

[14]

VS 2015

C++17

N4277

Trivially Copyable reference_wrapper

[14]

VS 2015

C++17

N4279

insert_or_assign()/try_emplace() For map/unordered_map

[14]

VS 2015

C++17

N4280

size(), empty(), data()

[14]

VS 2015

C++17

N4366

Precisely Constraining unique_ptr Assignment

[14]

VS 2015

C++17

N4389

bool_constant

[14]

VS 2015

C++17

P0063R3

C11 Standard Library

[C11] [14]

VS 2013

C++17

N4510

Supporting Incomplete Types In vector/list/forward_list

[14]

 

  • “…”: For clarity, the Library Fundamentals V1 paper has been decomposed into its individual features, marked by “…” here. The <memory_resource> header will be available in VS 2017 15.6, completing this paper.
  • missing vs. patch: To give you a better idea of our status, unimplemented papers are marked “missing” for primary features, or “patch” for papers that merely fixed parts of a primary feature. We implement them together, so the large number of “patch” rows doesn’t really indicate a large amount of missing work.
  • N/A: For clarity, this table has omitted a number of papers that are Not Applicable (nothing for implementers to do, or users to take advantage of), such as wording clarifications.
  • [14]: These C++17 features are implemented unconditionally, even in /std:c++14 mode (the default). For some features, this was because they predated the introduction of MSVC’s Standard mode options. For other features, conditional implementation would be nearly pointless or undesirably complicated.
  • [atomic]: This was almost completely implemented in VS 2017 15.3, and the remaining differences are difficult to observe (some signatures differ from the Standard, as observed by taking their address or providing explicit template arguments). The STL’s next major binary-incompatible version will fix the remaining differences.
  • [byte]: std::byte is enabled by /std:c++17, but has a fine-grained opt-out macro (_HAS_STD_BYTE can be defined to be 0). This is because given certain patterns of using-directives, it can conflict with the Windows SDK’s headers. This has been reported to the SDK team and will be fixed, but in the meantime the escape hatch is available.
  • [C11]: First available in VS 2015, the Universal CRT implemented the parts of the C11 Standard Library that are required by C++17, with minor exceptions. Those exceptions (which are tracked by bugs) are: missing C99 strftime() E/O alternative conversion specifiers, missing C11 fopen() exclusive mode, and missing C11 aligned_alloc(). The strftime() and fopen() functionality will be implemented in the future. aligned_alloc() will probably never be implemented, as C11 specified it in a way that’s incompatible with our implementation (namely, that free() must be able to handle highly aligned allocations).
  • [char_traits]: This will be partially available in VS 2017 15.6. The library changes have been implemented and tested, but they’re currently enabled for only the Clang and EDG compiler front-ends (which have implemented the compiler builtins that power this feature). When C1XX (MSVC’s compiler front-end) implements these builtins, we’ll mark this feature as complete.
  • [decay]: This paper is technically N/A, as it doesn’t require implementers to take action, and it doesn’t result in an observable feature for users. However, it improves compiler throughput, so we’ve gone ahead and implemented it unconditionally (as an exception to “C++17 before C++20”). This will ship in a VS 2017 update after 15.6 (denoted by “15.x” here).
  • [depr] and [rem]: See C++17 Feature Removals And Deprecations.
  • [DR]: These papers were voted into the Working Paper after C++17, but as Defect Reports, meaning that they retroactively apply to C++17 (as bugfixes).
  • [guides]: This will be partially available in VS 2017 15.6. The library changes have been implemented and tested, but they’re currently enabled for Clang only. (Testing MSVC’s STL with Clang found two compiler bugs, LLVM#34970 and LLVM#35045. We implemented a workaround for the former, which has been fixed for Clang 6. The latter appears to be extremely obscure and unlikely to be encountered by ordinary code.) When C1XX and EDG implement class template argument deduction, we’ll mark this feature as complete.
  • [obj_rep]: This type trait (powered by a compiler builtin) is currently enabled for C1XX only. The builtin was recently implemented in Clang, so when Clang 6 is released, we plan to enable the type trait for it. The type trait is also not yet enabled for EDG (which implemented the builtin earlier, but was affected by a compiler bug until recently).
  • [parallel]: We’re gradually implementing experimental support for the parallel algorithms.

 

Here are the parallel algorithms that we’ve implemented:

  • 15.5, intentionally not parallelized: copy, copy_n, fill, fill_n, move, reverse, reverse_copy, rotate, rotate_copy, swap_ranges. (The signatures for these parallel algorithms are added but not parallelized at this time; profiling showed no benefit in parallelizing algorithms that only move or permute elements.)
  • 15.5: all_of, any_of, for_each, for_each_n, none_of, reduce, replace, replace_if, sort.
  • 15.6 Preview 1: adjacent_find, count, count_if, equal, find, find_end, find_first_of, find_if, find_if_not.
  • 15.6 after Preview 1: mismatch, remove, remove_if, search, search_n, transform.
  • 15.x: partition, stable_sort.

 

Compiler Feature Status:

C++03/11/14 Core Language Features

Status

Paper

Notes

[Everything else]

VS 2017

 

[throw()]

Two-phase name lookup

Partial

 

[twoPhase]

Expression SFINAE

Partial

N2634

[exprSFINAE]

C99 preprocessor

Partial

N1653

[preprocessor]

C++17 Core Language Features

Status

Paper

Notes

Removing trigraphs

VS 2010

N4086

[14]

New rules for auto with braced-init-lists

VS 2015

N3922

[14]

typename in template template-parameters

VS 2015

N4051

[14]

Attributes for namespaces and enumerators

VS 2015

N4266

[14]

u8 character literals

VS 2015

N4267

[14]

Ignoring unrecognized attributes

VS 2015

P0283R2

[14]

Nested namespace definitions

VS 2015.3

N4230

 

Terse static_assert

VS 2017

N3928

 

Generalized range-based for-loops

VS 2017

P0184R0

[14]

[[fallthrough]] attribute

VS 2017

P0188R1

 

Removing the register keyword

VS 2017 15.3

P0001R1

 

Removing operator++ for bool

VS 2017 15.3

P0002R1

 

Capturing *this by value

VS 2017 15.3

P0018R3

 

Using attribute namespaces without repetition

VS 2017 15.3

P0028R4

 

__has_include

VS 2017 15.3

P0061R1

[14]

Direct-list-init of fixed enums from integers

VS 2017 15.3

P0138R2

 

constexpr lambdas

VS 2017 15.3

P0170R1

 

[[nodiscard]] attribute

VS 2017 15.3

P0189R1

 

[[maybe_unused]] attribute

VS 2017 15.3

P0212R1

 

Structured bindings

VS 2017 15.3

P0217R3

 

constexpr if-statements

VS 2017 15.3

P0292R2

[ifConstexpr]

Selection statements with initializers

VS 2017 15.3

P0305R1

 

Allowing more non-type template args

VS 2017 15.5

N4268

 

Fold expressions

VS 2017 15.5

N4295

and P0036R0

Removing dynamic-exception-specifications

VS 2017 15.5

P0003R5

 

Adding noexcept to the type system

VS 2017 15.5

P0012R1

 

Over-aligned dynamic memory allocation

VS 2017 15.5

P0035R4

 

Hexfloat literals

VS 2017 15.5

P0245R1

 

Inline variables

VS 2017 15.5

P0386R2

 

Matching template template-parameters to compatible arguments

VS 2017 15.5

P0522R0

 

Guaranteed copy elision

VS 2017 15.6

P0135R1

 

Fixing qualification conversions

No

N4261

 

Extended aggregate initialization

No

P0017R1

 

Class template argument deduction

No

P0091R3

and P0512R0

Declaring non-type template parameters with auto

No

P0127R2

 

Rewording inheriting constructors

No

P0136R1

 

std::launder()

No

P0137R1

[launder]

Refining expression evaluation order

No

P0145R3

and P0400R0

Pack expansions in using-declarations

No

P0195R2

 

Simplifying implicit lambda capture

No

P0588R1

[DR]

Fixing class template argument deduction for initializer-list ctors

No

P0702R1

[DR]

CWG 1581: When are constexpr member functions defined?

No

P0859R0

[DR]

 

  • [throw()]: In /std:c++14 mode, dynamic exception specifications remain unimplemented, and throw() is still treated as a synonym for __declspec(nothrow). In C++17, dynamic exception specifications were mostly removed by P0003R5, leaving one vestige: throw() is deprecated and required to behave as a synonym for noexcept. In /std:c++17 mode, MSVC now conforms to the Standard by giving throw() the same behavior as noexcept, i.e. enforcement via termination. The compiler option /Zc:noexceptTypes- requests our old behavior of __declspec(nothrow). It’s likely that throw() will be removed in C++20. To help with migrating code in response to these changes in the Standard and our implementation, new compiler warnings for exception specification issues have been added under /std:c++17 and /permissive- as documented here.
  • [twoPhase]: Two-phase name lookup is partially implemented in VS 2017 15.5 and 15.6, with an increasing number of scenarios working. Please read our Sept 2017 post for more details. The compiler front-end team is monitoring progress via approximately 85 test cases taken from in-house and external test suites and real codebases, with approximately 68% of them passing as of Dec 2017.
  • [exprSFINAE]: Expression SFINAE has been partially implemented in VS 2017 RTM through 15.6. While many scenarios work (and it has been sufficient for the STL’s purposes for 2 years), some parts are still missing and some workarounds are still required, like the “unique tag type” workaround. As the Parse Tree Rejuvenation effort progresses forward, we’ll be able to support dependent name binding inside decltype expressions, which will help us complete Expression SFINAE. This completion will require the /permissive- mode as it will depend on two-phase name lookup.
  • [preprocessor]: Support for C99’s preprocessor rules is unchanged (considered partial due to support for variadic macros, although there are numerous bugs). We’re overhauling the preprocessor, and we’ll experimentally ship those changes under the /permissive- mode soon.
  • [ifConstexpr]: “if constexpr” is supported in /std:c++14 with a warning that can be suppressed, delighting template metaprogramming library authors everywhere.
  • [launder]: std::launder(), which is 99.9% compiler magic, is currently listed in the compiler feature table, although we may move it to the library feature table in the future.

 

STL Fixes:

The following fixes are available in VS 2017 15.5, unless otherwise specified as appearing in VS 2017 15.6.

 

Significant Changes:

  • The STL is now tested with Clang/LLVM 5.0.0 (in our internal test suites and libc++’s test suite) and no longer supports Clang/C2 3.8.
  • The STL now identifies itself with two macros, defined by including any STL header (e.g. <ciso646>). _MSVC_STL_VERSION is defined as 141 and will remain that way for the VS 2017 v141 toolset series. _MSVC_STL_UPDATE is defined as 201709 in VS 2017 15.5, and will be increased as features are added in future updates. (The year-month typically won’t correspond to an update’s release date. Our process for updating this macro is “we’re checking in std::meow() and it’s now October, so we need to change the value”, and depending on branch/merge timing, it might take a month or more to ship.) The value for VS 2017 15.6 is not yet set in stone, but it will be 201711 or greater.

 

New Warnings And Errors:

  • Including <execution> now emits “warning STL4019: Parallel algorithms support is experimental in this release of Visual C++. Object files and static libraries that include <execution> may need to be rebuilt to link with a future update of Visual C++, and programs using <execution> may not run on Windows XP. This warning will be removed when parallel algorithms support is completed in a future update. You can define _SILENCE_PARALLEL_ALGORITHMS_EXPERIMENTAL_WARNING to acknowledge that you have received this warning.”
  • (15.6) Added a compiler/STL version mismatch check (with an escape hatch, _ALLOW_COMPILER_AND_STL_VERSION_MISMATCH). Our STL is tested with the corresponding version of C1XX, and they’re treated as a unit by the IDE. (That is, selecting an older toolset will use an older C1XX and a correspondingly older STL.) Our STL is also tested with the latest released version of Clang/LLVM. Mixing an older STL with a newer compiler is untested and unsupported, but will typically work. (For example, using Clang 6 with VS 2017 15.5.) However, because the STL’s implementation is constantly evolving to consume freshly-implemented compiler features and bugfixes, mixing a newer STL with an older compiler is a recipe for doom. By adding a version mismatch check, we can emit a comprehensible error message when imminent doom is detected. Currently, we check C1XX’s version with “#if _MSC_VER < 1912” and emit “#error STL1001: Unexpected compiler version, expected MSVC 19.12.” We also check Clang’s version with “#if __clang_major__ < 5” and emit “#error STL1000: Unexpected compiler version, expected Clang 5.” (We currently don’t check EDG’s version, or that of any other front-ends.) In the future, we will regularly increase the versions being checked here. (For subtle reasons, the lower bound for C1XX’s version being checked here may not always correspond to the version number that it’s actually shipping with. For example, VS 2017 RTM (15.0) was compiler version 19.10, VS 2017 15.3 was 19.11, VS 2017 15.5 was 19.12, and VS 2017 15.6 will be 19.13. While 15.6’s STL is shipping with and being tested with the 19.13 compiler, its version mismatch check will accept 19.12. This is because a checked-in copy of the toolset is used to build the shipping toolset, and at the time that 15.6 branched for release, the checked-in toolset was still identifying itself as 19.12. We might clarify the error message in the future by adding “or newer”.)
  • (15.6) The [[nodiscard]] attribute has been applied to nearly 2,500 functions in the STL. In /std:c++17 mode, this will emit a compiler warning when the return value of a function is being discarded instead of stored or inspected. (The warning can be portably and locally suppressed by casting to void.) We’ve carefully chosen which functions to mark with [[nodiscard]], so that the warnings will be valuable instead of noisy. Our criteria for emitting the warning are: discarding the return value is a guaranteed leak (e.g. std::allocator::allocate(), but not unique_ptr::release() – this was a judgement call), discarding the return value is near-guaranteed to be incorrect (e.g. remove()/remove_if()/unique()), or the function is essentially a pure observer (e.g. vector::empty() and std::is_sorted()). If you encounter these [[nodiscard]] warnings, we believe it’s highly likely that your code contains a bug, so please think about it instead of reflexively suppressing the warning because it previously compiled cleanly. For example, confusion between vector’s empty() (an observer returning bool) and clear() (an action returning void) is common among beginning programmers, and will be detected by this warning. Even in our own compiler’s codebase, we encountered a case where an array was being given to is_sorted() and then the returned bool was discarded; the intention was to assert that the array was sorted.

 

Correctness Fixes:

  • random_device::entropy() is now marked as const.
  • map/multimap::value_compare’s constructor is now protected, following the Standard.
  • Increased conformance by avoiding a non-Standard compiler extension (in-class explicit specializations) within the iostreams implementation.
  • The STL now adapts to whether the compiler provides C++17’s behavior for noexcept (e.g. is_function detects noexcept-qualified function types). The STL also avoids throw().
  • is_partitioned() was incorrectly calling the predicate N + 1 times, instead of N times as required by the Standard.
  • atomic<T> no longer requires T to be default constructible.
  • basic_string::npos is now available as a compile time constant.
  • std::allocator now properly handles allocation of over-aligned types (whose alignment is greater than max_align_t) in C++17 mode (unless disabled by /Zc:alignedNew-). For example, vectors of objects with 16 or 32-byte alignment will now be properly aligned for SSE/AVX instructions.
  • shared_ptr’s constructors now handle nullptrs with custom deleters, and unique_ptrs with fancy pointers and custom deleters.
  • Fixed a bug in scoped_allocator_adaptor::select_on_container_copy_construction() with 3+ allocators.
  • We constrained std::function’s converting constructor/assignment to avoid competing with copy/move construction/assignment. This avoids bizarre compiler errors in certain situations.
  • (15.6) Fixed a regression that was introduced in VS 2017 15.5, where compiling with /clr and including STL headers within #pragma managed(push, off) (contrary to the documentation’s guidance) started emitting compiler errors. We now tolerate this scenario again, while still avoiding the extremely fragile non-Standard extension __if_exists.
  • (15.6) ratio_less now avoids integer overflow with extreme inputs.
  • (15.6) sort() now uses difference_type instead of size_t. Other algorithms now respect difference_types that aren’t ptrdiff_t.
  • (15.6) Fixed a regression that was introduced in VS 2017 15.5, where including <numeric> with /fp:except emitted a compiler error.
  • (15.6) The STL now supports over-aligned temporary buffers, and therefore supports algorithms on ranges of over-aligned types.

 

Performance/Throughput Fixes:

  • Improved the performance of forward_list::empty() in debug mode.
  • Heap algorithms that take logarithmic time no longer do a linear time assertion that the input is in fact a heap in debug mode.
  • basic_string<char16_t> now engages memcmp()/memcpy()/etc. optimizations that basic_string<wchar_t> engages. Note that constexpr char_traits in VS 2017 15.6 partially reverts this work due to compiler limitations; see LLVM#35165 for more info.
  • An optimizer limitation (which prevented function pointers from being inlined) that was exposed by our “avoid copying function objects” work in VS 2015.3 has been worked around, restoring the performance of lower_bound(iter, iter, function pointer).
  • The overhead of iterator debugging’s order verification of inputs to includes(), set_difference(), set_symmetric_difference(), and set_union() was reduced by unwrapping iterators before checking order.
  • inplace_merge() now skips over elements that are already in position.
  • Constructing random_device no longer constructs and then destroys a std::string.
  • equal() and partition() received a jump-threading optimization pass which saves an iterator comparison.
  • When reverse() is given pointers to trivially copyable T, it will now dispatch to a handwritten vectorized implementation. This can increase performance by up to 8x (times, not percent).
  • fill(), equal(), and lexicographical_compare() were taught how to dispatch to memset()/memcmp() for std::byte and gsl::byte (and other char-ish enums and enum classes). Note that copy() dispatches using is_trivially_copyable and thus didn’t need any changes.
  • The STL no longer contains empty-braces destructors whose only behavior was to make types non-trivially-destructible.
  • Slightly improved codegen size for dual-range, non-random-access equal().
  • (15.6) Significantly improved compiler throughput when including <ppltasks.h>, which is included by our implementation of <future>.
  • (15.6) Significantly improved the performance of find_end().
  • (15.6) Improved the performance of dual-range mismatch() for random-access iterators.
  • (15.6) Improved the performance of search() by calling memcmp() when possible.
  • (15.6) Improved the performance of string/string_view’s find_first_of() family by using bitmaps.

 

Readability And Other Improvements:

  • The STL now uses variable templates internally.
  • __declspec(allocator) is now guarded for C1XX only, to prevent warnings from Clang which doesn’t understand this declspec.
  • The STL now tolerates /Zc:threadSafeInit- which disables magic statics. (We attempted to tolerate this compiler option in VS 2017 15.3, but the attempt was incomplete.)
  • We dramatically improved the experience of debugging into a std::function call. See our Nov 2017 post for more info. Note that this triggers LLVM#31944 (a Clang bug with PCHes) which has been fixed in Clang 6.
  • The STL works with “Just My Code” in the debugger again.
  • In release mode, marked forward_list’s default/move constructors as noexcept.
  • (15.6) Strengthened noexcept on the constructors and assignment operators of containers and container adaptors to reflect their implementations.

 

C++20:

We’re working on finishing C++17 before starting C++20. For completeness, here are the rest of the papers that have been voted into the C++20 Working Paper. (While we’ve added many [[nodiscard]] attributes to our codebase, P0600R1 is not yet complete.)

 

Status

Std

Paper

Title

Notes

missing

C++20

P0020R6

atomic<float>, atomic<double>, atomic<long double>

 

missing

C++20

P0053R7

<syncstream>

 

missing

C++20

P0202R3

constexpr For <algorithm> And exchange()

 

missing

C++20

P0415R1

constexpr For <complex> (Again)

 

missing

C++20

P0439R0

enum class memory_order

 

missing

C++20

P0457R2

starts_with()/ends_with() For basic_string/basic_string_view

 

missing

C++20

P0463R1

endian

 

missing

C++20

P0550R2

remove_cvref

 

missing

C++20

P0600R1

[[nodiscard]] For The STL, Part 1

[nodiscard]

missing

C++20

P0616R0

Using move() In <numeric>

 

missing

C++20

P0653R2

to_address()

 

missing

C++20

P0674R1

make_shared() For Arrays

 

missing

C++20

P0718R2

atomic<shared_ptr<T>>, atomic<weak_ptr<T>>

[depr]

missing

C++20

P0767R1

Deprecating is_pod

[depr]

missing

C++20

P0768R1

Library Support For The Spaceship Comparison Operator <=>

[depr]

 

C++20 Core Language Features

Status

Paper

Notes

Adding __VA_OPT__ for comma omission and comma deletion

No

P0306R4

 

Allowing lambdas in unevaluated contexts

No

P0315R4

 

Designated initialization

No

P0329R4

 

Allowing lambda-capture [=, this]

No

P0409R2

 

Familiar template syntax for generic lambdas

No

P0428R2

 

Three-way (spaceship) comparison operator <=>

No

P0515R3

 

Range-based for-loops with initializers

No

P0614R1

 

Default constructible and assignable stateless lambdas

No

P0624R2

 

CWG 1331: const mismatch with defaulted copy constructor

No

P0641R2

 

Default member initializers for bit-fields

No

P0683R1

 

Relaxing access checking on specializations

No

P0692R1

 

Fixing const lvalue ref-qualified pointers to members

No

P0704R1

 

Concepts

No

P0734R0

 

ADL and function templates that are not visible

No

P0846R0

 

Fixing functionality gaps in constraints

No

P0857R0

 

 

Reporting Bugs:

Please let us know what you think about VS 2017 15.5 and 15.6. You can report bugs via the IDE’s Report A Problem and also via the web: go to the VS Developer Community and click on the C++ tab. For compiler and library bugs, it’s important to provide self-contained test cases.

 

Happy holidays from your C++ Standard Library implementers (and the rest of the Visual C++ team!):