{"id":28674,"date":"2021-09-02T21:18:28","date_gmt":"2021-09-02T21:18:28","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=28674"},"modified":"2021-09-02T21:20:36","modified_gmt":"2021-09-02T21:20:36","slug":"msvc-cpp20-and-the-std-cpp20-switch","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/msvc-cpp20-and-the-std-cpp20-switch\/","title":{"rendered":"MSVC C++20 and the \/std:c++20 Switch"},"content":{"rendered":"<p>We are excited to announce that in Visual Studio 2019 version 16.11, we have added the <code>\/std:c++20<\/code> switch to the set of language mode switches available. The addition of this switch indicates that we\u2019ve reached a point of sufficient stabilization of the MSVC C++20 feature set for it be used in production, with full support in VS servicing updates.<\/p>\n<p>This blog post focuses on describing our level of C++20 feature support, compiler-supported extensions, and the remaining feature set differences between MSVC and the ISO C++ standard as of Visual Studio 2019 version 16.11 and Visual Studio 2022 version 17.0<\/p>\n<h2><span style=\"font-size: 18pt;\">C++ Language Modes and Compatibility Guarantees<\/span><\/h2>\n<p>First <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/standards-version-switches-in-the-compiler\/\">introduced in Visual Studio 2015<\/a>, the MSVC compiler has included C++ language mode switches to indicate the targeted level of standard conformance and we now support three stable language modes: <code>\/std:c++14<\/code>, <code>\/std:c++17<\/code>, <code>\/std:c++20<\/code> (as of VS 2019 v16.11) and one preview mode (<code>\/std:c++latest<\/code>).<\/p>\n<p>The stable modes indicate that features under those modes are ready for production use and have ABI compatibility guarantees. The <code>\/std:c++latest<\/code> mode contains ISO C++ features without strong guarantees for compatibility, allowing iteration based upon issues identified in testing, ISO C++ standard changes, and community feedback which may impact ABI stability of those features. Once stabilized, features under \/std:c++latest will be moved under an applicable stable mode.<\/p>\n<table>\n<tbody>\n<tr>\n<td width=\"105\"><strong>Language Mode<\/strong><\/td>\n<td width=\"219\"><strong>Language Mode enables strict-conformance (\/permissive-)<\/strong><\/td>\n<td width=\"91\"><strong>ABI Stable<\/strong><\/td>\n<td width=\"208\"><strong>Notes<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"105\">\/std:c++14<\/td>\n<td width=\"219\">No<\/td>\n<td width=\"91\">Yes<\/td>\n<td width=\"208\">See <strong>**<em>Note A<\/em><\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"105\">\/std:c++17<\/td>\n<td width=\"219\">No<\/td>\n<td width=\"91\">Yes<\/td>\n<td width=\"208\">See <strong>**<em>Note A<\/em><\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"105\">\/std:c++20<\/td>\n<td width=\"219\">Yes<\/td>\n<td width=\"91\">Yes<\/td>\n<td width=\"208\">See <strong>**<em>Note B<\/em><\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"105\">\/std:c++latest<\/td>\n<td width=\"219\">Yes<\/td>\n<td width=\"91\">No<\/td>\n<td width=\"208\">See <strong>**<em>Note B<\/em><\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong><em>**<\/em><\/strong><strong><em>Note A<\/em><\/strong><em>: Strict conformance mode is opt-in via the \/permissive- compiler switch<\/em><\/p>\n<p><strong><em>**Note B<\/em><\/strong><em>: Some functionality such as C++20 Modules require strict-conformance mode to be enabled due to strong dependency on ISO C++ semantic behaviors. Compatibility mode (\/permissive) is supported as an opt-in switch \u00a0with some C++20 functionality disabled.<\/em><\/p>\n<h2><span style=\"font-size: 18pt;\">C++20 Features added in VS 2019 v16.9 and later<\/span><\/h2>\n<p>Below is a summary of language and library C++20 features implemented since the last feature update.<\/p>\n<p>A more detailed <a href=\"https:\/\/github.com\/microsoft\/STL\/wiki\/Changelog\">changelog<\/a> is available for <a href=\"https:\/\/github.com\/microsoft\/STL\">the STL on its GitHub repo<\/a> including information on the awesome community contributors who have provided feature implementations and bug fixes to the STL<\/p>\n<h3><span style=\"font-size: 14pt;\">VS 2019 v16.9<\/span><\/h3>\n<p>C++20 Language Features<\/p>\n<ul>\n<li>Implemented <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2018\/p0634r3.html\">P0634R3<\/a> Down with typename!<\/li>\n<li>Implemented <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2018\/p0840r2.html\">P0840R2<\/a> [[no_unique_address]] attribute (<em>please see below for more details<\/em>)<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1064R0\">P1064R0<\/a> Allowing virtual function calls in constant expressions<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1141R2\">P1141R2<\/a> Yet another approach for constrained declarations<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1327R1\">P1327R1<\/a> Allowing dynamic_cast, polymorphic typeid in constant expressions<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1668R1\">P1668R1<\/a> Permitting unevaluated inline assembly in constexpr functions<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0784R7\">P0784R7<\/a> More constexpr containers<\/li>\n<\/ul>\n<p>C++20 Library Features<\/p>\n<ul>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0339R6\">P0339R6<\/a> polymorphic_allocator&lt;&gt;<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0660R10\">P0660R10<\/a> &lt;stop_token&gt; And jthread<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0768R1\">P0768R1<\/a> Library Support For The Spaceship Comparison Operator &lt;=&gt;<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1007R3\">P1007R3<\/a> assume_aligned()<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1020R1\">P1020R1<\/a> Smart Pointer Creation With Default Initialization<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1771R1\">P1771R1<\/a> [[nodiscard]] For Constructors<\/li>\n<\/ul>\n<h3><span style=\"font-size: 14pt;\">VS 2019 v16.10 &amp; v16.11<\/span><\/h3>\n<p>C++20 Language Features<\/p>\n<ul>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1073R3\">P1073R3<\/a> Immediate functions<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1143R2\">P1143R2<\/a> constinit<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1353R0\">P1353R0<\/a> Missing feature-test macros<\/li>\n<\/ul>\n<p>C++20 Library Features<\/p>\n<ul>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0053R7\">P0053R7<\/a>&lt;syncstream&gt;<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0355R7\">P0355R7<\/a>&lt;chrono&gt; Calendars And Time Zones<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0408R7\">P0408R7<\/a> Efficient Access To basic_stringbuf&#8217;s Buffer<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0466R5\">P0466R5<\/a> Layout-Compatibility And Pointer-Interconvertibility Traits<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0475R1\">P0475R1<\/a> Guaranteed Copy Elision For Piecewise Construction<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0591R4\">P0591R4<\/a> Utility Functions For Uses-Allocator Construction<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0608R3\">P0608R3<\/a> Improving variant&#8217;s Converting Constructor\/Assignment<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0645R10\">P0645R10<\/a> &lt;format&gt; Text Formatting<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0784R7\">P0784R7<\/a> Library Support For More constexpr Containers<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0896R4\">P0896R4<\/a> Ranges<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P0980R1\">P0980R1<\/a> constexpr std::string<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1004R2\">P1004R2<\/a> constexpr std::vector<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1208R6\">P1208R6<\/a> &lt;source_location&gt;<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1502R1\">P1502R1<\/a> Standard Library Header Units<\/li>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P1614R2\">P1614R2<\/a> Adding Spaceship &lt;=&gt; To The Library<\/li>\n<\/ul>\n<h2><span style=\"font-size: 14pt;\">VS 2022 17.0 (still in Preview)<\/span><\/h2>\n<p>C++20 Language Features<\/p>\n<ul>\n<li>Completed implementation of <a href=\"https:\/\/wg21.link\/P0734R0\">P0734R0<\/a> Concepts<\/li>\n<\/ul>\n<p>C++20 Library DRs<\/p>\n<ul>\n<li>Implemented <a href=\"https:\/\/wg21.link\/P2325R3\">P2325R3<\/a> Views Should Not Be Required To Be Default Constructible<\/li>\n<\/ul>\n<h2><span style=\"font-size: 18pt;\">ISO C++20\u00a0 Continuing Work, Defect Reports, and Clarifications<\/span><\/h2>\n<p>As part of implementing C++20, there were some late discoveries which required changes to the ISO C++20 standard via the standard committee\u2019s Defect Report (DR) process. This included Existing implementations (pre-DR) for these features are available under the <code>\/std:c++latest<\/code> switch.\u00a0 We\u2019re also tracking the DRs and are implementing those issue resolutions under <code>\/std:c++latest<\/code>. Our plan is to make these capabilities available under the <code>\/std:c++20<\/code> switch after implementation of the full set of Standard Library DRs has completed. Progress on these features can be tracked on the <a href=\"https:\/\/github.com\/microsoft\/STL\">MSVC STL GitHub site<\/a> through its <a href=\"https:\/\/github.com\/microsoft\/STL\/projects\/9\">C++20 DRs project<\/a>.<\/p>\n<p>In the compiler, we are working with ISO C++ and other toolchain vendors to clarify expectations around allowing virtual functions to be <code>constexpr<\/code> (<a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2018\/p1064r0.html\">P1064R0<\/a>). There are a couple of possibilities for implementation, which have significant ABI implications as to whether this is implemented via vtable entry. In the interim, we have implemented two modes, under <code>\/experimental:constevalVfuncVtable<\/code> and <code>\/experimental:constevalVfuncNoVtable<\/code>, which implement the most likely resolutions to this ambiguity. Once a decision is made on how to proceed, we\u2019ll bring that capability under <code>\/std:c++20<\/code> and <code>\/std:c++latest<\/code>.<\/p>\n<p>Additionally, there were some feature areas that were unintentionally partially implemented. We are working to get those areas filled. For VS 2022 v17.0, we have implemented the requires-expression portion of the Concepts feature (<a href=\"https:\/\/wg21.link\/P0734R0\">P0734R0<\/a>), which is scheduled to ship in VS 2022 v17.0.\u00a0 We\u2019re also working to complete implementation of <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2017\/p0859r0.html\">Core Issue 1581<\/a>: \u201cWhen are constexpr member functions defined?,\u201d which is tracking towards inclusion in a VS 2022 update after v17.0.<\/p>\n<h2><span style=\"font-size: 18pt;\">MSVC Extensions and ABI<\/span><\/h2>\n<h3><span style=\"font-size: 14pt;\">C++20 <code>[[no_unique_address]]<\/code><\/span><\/h3>\n<p>Implementation of C++20 <code>[[no_unique_address]]<\/code> included a couple of additional challenges due to the ABI-breaking impact (changing object layout) of applying this optimization. This is problematic due to the MSVC compiler ignoring attributes that are not known, as allowed by the standard, resulting in scenarios where MSVC ABI compatibility guarantees would be broken for standard C++ code:<\/p>\n<ul>\n<li>Compiling the same header\/source under <code>\/std:c++17<\/code> and <code>\/std:c++20<\/code> would result in link-time incompatibilities due to object layout differences resulting in ODR violations.<\/li>\n<li>Linking static libraries built with an older version of the MSVC compiler (VS 2015 through VS 2019 v16.8), within the v14x ABI-compatible family, would result in ODR violations and break our compatibility guarantees.<\/li>\n<\/ul>\n<p>It was decided to hold-off on enabling the optimization for the <code>[[no_unique_address]]<\/code> attribute in the MSVC compiler until our next ABI breaking revision of the MSVC toolset, where it will be enabled across all language modes.<\/p>\n<p>However, we do recognize that there are some customers who are in a position to take advantage of this optimization without worrying about linking binaries across versions of the MSVC toolset.\u00a0 For this audience, we have made this optimization available in VS 2019 v16.9 and later through an extension attribute that affects optimization across all compiler language modes, <code>[[msvc::no_unique_address]]<\/code>.<\/p>\n<ul>\n<li>There are portability concerns for customers who require ABI-compatiblity between MSVC and Clang for the STL. Please see <a href=\"https:\/\/github.com\/microsoft\/STL\/issues\/1364\">https:\/\/github.com\/microsoft\/STL\/issues\/1364<\/a> for more details.<\/li>\n<li>This extension attribute enables this optimization under all C++ language modes (e. <code>\/std:c++14<\/code>, <code>\/std:c++17<\/code>, <code>\/std:c++20<\/code>, <code>\/std:c++latest<\/code>.<\/li>\n<li>We strongly recommend that any usage of this attribute is guarded by an MSVC version-check as demonstrated in the below example:<\/li>\n<\/ul>\n<pre class=\"prettyprint\">#include &lt;iostream&gt;\r\n\r\n#if _MSC_VER &gt;= 1929 \/\/ VS2019 v16.10 and later (_MSC_FULL_VER &gt;= 192829913 for VS 2019 v16.9)\r\n\/\/ Works with \/std:c++14 and \/std:c++17, and performs optimization\r\n\r\n#define NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]\r\n\r\n#else\r\n\r\n\/\/ no-op in MSVC v14x ABI\r\n#define NO_UNIQUE_ADDRESS \/* [[no_unique_address]] *\/\r\n\r\n#endif\r\n\r\n\r\nstruct Empty {};\r\n\r\nstruct A\r\n{\r\n\u00a0\u00a0\u00a0 int a;\r\n\u00a0\u00a0\u00a0 NO_UNIQUE_ADDRESS Empty b;\r\n};\r\n\r\nint main()\r\n{\r\n\u00a0\u00a0\u00a0 A inst{ 0 };\r\n\r\n\u00a0\u00a0\u00a0 \/\/ [[msvc::no_unique_address]] : sizeof(inst) == 4.\r\n\u00a0\u00a0\u00a0 \/\/ [[no_unique_address]] : sizeof(inst) == 8.\r\n\u00a0\u00a0\u00a0 std::cout &lt;&lt; sizeof(inst) &lt;&lt; \"\\n\";\r\n}<\/pre>\n<h3><span style=\"font-size: 14pt;\">C++20 Coroutine support for C++14\/C++17 (<code>\/await:strict<\/code>)<\/span><\/h3>\n<p>The <code>\/await:strict<\/code> option can be used in place of <code>\/await<\/code> for C++20 compatible coroutine support in projects that build in C++14 or C++17 mode. In <code>\/await:strict<\/code> mode library support is provided in <code>&lt;coroutine&gt;<\/code> and in the std namespace. For full clarity, this behavior is on-by-default under <code>\/std:c++20<\/code> without any <code>\/await*<\/code> switch usage.<\/p>\n<p>Strict mode disables language extensions present in\u00a0<code>\/await<\/code>\u00a0that were not adopted into the C++20 standard. Use\u00a0 of such features with <code>\/await:strict<\/code> will result in a compiler error. Strict mode also implements coroutine behaviors such as promise parameter preview that are not available under\u00a0<code>\/await<\/code>\u00a0due to binary compatibility issues with older releases.<\/p>\n<p>Note: coroutine state objects obtained from <code>coroutine_handle&lt;T&gt;::address()<\/code> are not compatible between <code>\/await<\/code> and <code>\/await:strict<\/code> modes. Using <code>coroutine_handle&lt;T&gt;::from_address()<\/code> on an address obtained from a coroutine handle created in an incompatible mode will result in undefined behavior.<\/p>\n<h2><span style=\"font-size: 18pt;\">More Information<\/span><\/h2>\n<p>For Visual Studio changes (beyond the C++ toolset) and download links, see the\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/releases\/2019\/release-notes\">VS 2019 Release Notes<\/a> and\u00a0 <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/releases\/2022\/release-notes-preview\">VS 2022 Preview Release Notes<\/a>. You can report bugs through <a href=\"https:\/\/developercommunity.visualstudio.com\/spaces\/62\/index.html\">Developer Community<\/a>, and you can also report STL bugs via\u00a0<a href=\"https:\/\/github.com\/microsoft\/STL\/issues\">microsoft\/STL GitHub issues<\/a>.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We are excited to announce that in Visual Studio 2019 version 16.11, we have added the \/std:c++20 switch to the set of language mode switches available. The addition of this switch indicates that we\u2019ve reached a point of sufficient stabilization of the MSVC C++20 feature set for it be used in production, with full support [&hellip;]<\/p>\n","protected":false},"author":44789,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-28674","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>We are excited to announce that in Visual Studio 2019 version 16.11, we have added the \/std:c++20 switch to the set of language mode switches available. The addition of this switch indicates that we\u2019ve reached a point of sufficient stabilization of the MSVC C++20 feature set for it be used in production, with full support [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/28674","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\/44789"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=28674"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/28674\/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=28674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=28674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=28674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}