On the circular path from RAII to crazy-town back to RAII: Thoughts on emulating C#'s using in C++

Date:July 10, 2017 / year-entry #157
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20170710-00/?p=96565
Comments:    4
Summary:A trip around the block.

Some follow-up notes on Emulating the C# using keyword in C++, primarily for the benefit of people from reddit who stumbled into the series and didn't understand the context of the discussion, because this was really part 6 of the series begun the previous week, even though it wasn't labeled as such. (And the title itself was a party trick rather than a serious proposal.)

The main complication that prevented us from using RAII was the use of the Parallel Patterns Library (PPL) to express asynchronous programming in C++.¹ The most general pattern for asynchronous programming is that you start an operation, and then specify a callback to be invoked when the operation completes. In traditional C-style programming, this callback is a boring function pointer, coupled with some reference data so the callback has context for why it is being called back. C++ provides lambdas which let you express the continuation as a callback object, which is much more convenient since you can express the control flow inline instead of having tiny pieces of control flow scattered all over your program. And lambda capture makes it easy to express what pieces of information needs to be carried forward to the continuation.

If we didn't have any asynchronous operations, then a basic RAII class would do the trick: When the RAII class destructs, the cleanup operation occurs. (In our example, the cleanup operation is calling Close.) The difficulty in the asynchonous case is that it is cumbersome to keep carrying this RAII class forward and preventing it from destructing until the entire chain of continuations has completed. That's where the ensure_close and shared_close classes entered the picture. But you still had to remember to carry them forward.

The magical step was the introduction of the not-yet-standard-but-hopefully-soon co_await keyword. This transforms the function into a state machine, where each co_await represents the end of a state. The current execution state is saved, and execution of the task suspends. When the awaited operation completes, the execution state is restored and the function resumes execution. This transformation is very tedious and error-prone to perform by hand (especially when there are loops and branches), and in particular, it preserves RAII semantics: The automatic variables created by the pre-transformed function become part of the execution state, and they are destructed at the "natural" time they would have been destructed prior to transformation.

As a result, switching to co_await brings us full circle back to plain old RAII. Behind the scenes, the compiler is doing the wacky transformations that we tried to mimic with ensure_close and shared_close. But co_await lets us write the code in a far more natural way.

¹ There's also std::future, but its lack of composability makes it a poor choice for asynchronous programming.


Comments (4)
  1. kantos says:

    Having recently used co_await with cppwinrt for some sockets code it is indeed wonderful magical pixie dust that I can’t wait to get fully standardized.

  2. Mathias Gaunard says:

    The concurrency TS has future::then, which makes it composable.

  3. This is probably the blog platform’s fault and out of your control, but the social links on this article have some busted HTML with unescaped quotes in their attributes:

    <a data-social='{"type":"twitter", "url":"https://blogs.msdn.microsoft.com/oldnewthing/20170710-00/?p=96565&quot;, "text": "On the circular path from RAII to crazy-town back to RAII: Thoughts on emulating C#'s using in C++”}’ href=”#” id=”post_tweet_count”>0

    Workaround: remove the apostrophe from the article title, since other articles aren’t quite as busted as this one.

    1. Yeah, I’ve opened a ticket with the blog platform team. Meanwhile, I changed the ‘ to &#39; to work around the problem. They asked me to turn the corruption back on so they can investigate.

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index