

C++20 Coroutine Improvements in Visual Studio 2019 version 16.11
source link: https://devblogs.microsoft.com/cppblog/cpp20-coroutine-improvements-in-visual-studio-2019-version-16-11/?WT_mc_id=DOP-MVP-4025064
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C++20 Coroutine Improvements in Visual Studio 2019 version 16.11
Jonathan
August 31st, 2021
This post includes contributions from Terry Mahaffey and Ramkumar Ramesh.
We last blogged about coroutine support in Visual Studio 2019 version 16.8. In the releases since 16.8 we’ve introduced several new coroutine features and improvements. This post is a round up of those improvements, all available in Visual Studio 2019 16.11.
Debugging Improvements
Since Visual Studio 2019 version 16.9, stepping into a coroutine call will now land directly in the coroutine body (unless it is set to initially suspend, in which case the step becomes a “step over”). Stepping over a co_await
will land in the logical statement following co_await
for the coroutine – which may be in a completely different execution context (even another thread)! This allows stepping through coroutines to seamlessly match the logical flow of the application and skip intermediate implementation details. For the best debugging experience, implementation details of the coroutine state should be marked as non-user code. Stepping through coroutines now also shows function parameters as expected in the Locals window so you can see the state of the application, similar to stepping through synchronous functions.
Inspecting the state of a suspended coroutine is now easier with some improvements to the debugging visualizers for standard coroutines. The legacy coroutine_handle
visualizers could display special indicators for the initial and final suspend points, but only showed a number for other suspend points. This number was not always easy to map back to a particular point in the original coroutine. The visualizer also showed the name of the coroutine but only as a modified, internal name generated by the implementation with no signature information.

With the new coroutine handle visualizer introduced in Visual Studio 2019 16.10 the function name is now correct and includes full signature information to help distinguish overloaded coroutines. The suspend point information for suspend points other than initial and final suspend also includes the source line number to make it easier to find.

/await:strict
The earlier blog post outlines some issues with legacy await mode and the rationale for keeping the /await
switch distinct from C++20 coroutine support in /std:c++latest
. Legacy mode is useful for users who were early adopters of C++ coroutines, but they are not standard coroutines.
/await
switch predates not only our /std:c++latest
and /std:c++20
switches but also /std:c++17
. Early adopters were able to make use of coroutines long before they became part of the C++ standard. These users could use coroutines without requiring their code to be C++20 conformant or even necessarily C++17 conformant. With standard coroutines available only under C++20 and latest modes, early adopters of coroutines who cannot move their code to a more recent language version were stuck with the legacy implementation of coroutines under/await
. They could not take advantage of some new features like symmetric transfer and improved debugger support, even if they were willing to make source changes to the coroutines themselves to bring them in line with the C++20 standard./await:strict
. Using this switch instead of /await
enables the same C++20 coroutine support as standard mode but without all the other requirements of /std:c++20
. This includes support for all standard C++20 coroutine features and debugger integration and disables all the legacy extensions still supported under /await
. The only difference between /std:c++20
coroutines and /await:strict
is the latter does not define the spaceship operator for std::coroutine_handle
. Instead, it defines individual relational operators./await
to /await:strict
may require source changes if your code relies on extensions that were not adopted into C++20. Like Standard mode it uses the <coroutine>
header and the std
namespace, so your code will be drop-in ready for C++20. Code compiled with /await:strict
uses the same coroutine ABI as /std:c++latest
, so coroutine objects are compatible between the two modes./await
to migrate to /await:strict
. You can take advantage of all new coroutine features as well as ensure your coroutine code is ready for C++20 when you can move to a C++ language version that officially supports coroutines. We expect to deprecate and remove the /await
switch at some point in the future.Stability Improvements
Visual Studio 2019 version 16.11 also includes several important fixes to improve the stability and reliability of coroutines.
The largest change relates to how the optimizer does what is called “promotion”, which is the algorithm to decide which variables get placed on the coroutine frame and which variables remain on the (traditional) stack. Many coroutine bugs can be traced back to an incorrect decision here. Typically this shows up as a crash, or as a variable having an incorrect or random value after a coroutine resumes execution. This promotion algorithm has been rewritten to be more accurate, and the result is less crashes and a much smaller coroutine frame size overall. The old algorithm is still accessible by passing /d2CoroNewPromotion-
to cl.exe.
A related fix concerns how exception objects are stored. The lifetime rules for exceptions can get complicated, and they need to be handled specifically when it comes time to decide variable promotion.
A bug was found and fixed related to catch blocks in coroutines. Under certain circumstances (namely, when the only throwing call in a try block was from a user defined awaiter method) the optimizer could erroneously conclude a catch block was dead, and incorrectly remove it. The compiler is now aware that awaiter methods can throw.
Finally, a serious issue was resolved related to how and when destructors are invoked. This relates to how the construction state is tracked in coroutines for certain objects which are conditionally destroyed when leaving a scope. It comes up most when constructing objects when using the conditional (ternary) operator. The bug manifests itself by a destructor for such temporary objects not being invoked, or in certain cases invoked twice. This has also been fixed in 16.11.
Feedback
We urge you to try out C++ coroutines in Visual Studio, either with C++20 or now with /await:strict
, to see how asynchronous functions can help make your code more natural. As always, we welcome feedback on our coroutine implementation either in the comments below, or for bug reports and feature requests directly on Developer Community.
Jonathan Emmett
Senior Software Engineer, Visual C++
Follow
Recommend
-
14
Visual Studio 2019 for Mac version 8.8 is now availableVisual Studio 2019 for Mac version 8.8 is now available
-
15
Visual Studio 2019 version 16.8 Release Notes 12/08/2020
-
10
Improvements to the new Razor editor in Visual Studio
-
10
Visual Studio 2019 for Mac version 8.9 is now availableVisual Studio 2019 for Mac version 8.9 is now available
-
7
Announcing PostSharp 6.9 RC: Visual Studio Tooling performance improvements by Antonin Prochazka on 17 Mar 2021 We are happy to...
-
13
Announcing PostSharp 6.9: Visual Studio Tooling performance improvements by Lejla Rasic on 31 Mar 2021 Just 2 weeks after relea...
-
5
Visual Studio 2019 for Mac version 8.10 is now available
-
9
<format> in Visual Studio 2019 version 16.10 Charlie
-
8
Static Analysis Fixes, Improvements, and Updates in Visual Studio 2019 version 16.10 ...
-
7
Visual Studio 2019 version 16.11 will be the last version of Visual Studio 2019Visual Studio 2019 was first released on April 2, 2019, and since then it went through a couple of releases. The
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK