We want await! A C# talk that’s applicable to C++

A nice talk by Mads Torgersen just went live on Channel 9 about C#’s non-blocking Task<T>.ContinueWith() library feature and await language feature, which are a big hit in C# (and Visual Basic) for writing highly concurrent code that looks pretty much just like sequential code. Mads is one of the designers of await.

If you’re a C++ programmer, you may be interested in this because I’ve worked to have these very features be offered as proposals for ISO C++, just with a few naming tweaks like renaming Task<T>.ContinueWith() to std::future<T>::then(). They were initially presented at the recent Kona meeting in February, and we’ll dig deeper next month at the special ISO C++ study group meeting on concurrency and parallelism.

Here’s the talk link and abstract:

Language Support for Asynchronous Programming

Mads Torgersen

Asynchronous programming is what the doctor usually orders for unresponsive client apps and for services with thread-scaling issues. This usually means a bleak departure from the imperative programming constructs we know and love into a spaghetti hell of callbacks and signups. C# and VB are putting an end to that, reinstating all your tried-and-true control structures on top of a future-based model of asynchrony.

While we were chatting after the talk, I managed to gently twist Mads’ arm and he has graciously agreed to come to the May 7-9 ISO C++ parallelism study group special meeting to present this to the committee members in detail and answer questions about await’s design and C# users’ experience with it in production code, which will help the committee decide whether or not this is something they want to pursue for ISO C++.

I hope you enjoy the talk. While at Lang.NEXT, I also participated in a panel and gave a C++ talk but those sessions aren’t live yet; I’ll post links once they are.

Trivia: If you noticed the Romanian accent in the first question from the audience, it’s because it came from Andrei Alexandrescu, who was sitting beside Walter Bright, both of whom were two of the other speakers at the conference. It was fun to be in a room full of language designers and implementers sharing notes about each other’s languages and experience.

Reader Q&A: What does it mean for [[attributes]] to affect language semantics?

Followup on this earlier question, @bilbothegravatar asked:

@Alf, @Herb – I don’t quite get the [[noreturn]] example. While it may (not) compile on VC++, (as far as I understand) it does not carry any semantic meaning, and, what’s more, it is *perfectly* safe for any compiler that sees [[noreturn]] to just ignore it — the runtime behaviour vs. VC++ shouldn’t be changed at all.

So how is [[noreturn]] in the same camp as “restrict” ??? (I agree it may(?) be in the same camp as final and override.)

I will quote Bjarne: (http://www2.research.att.com/~bs/C++0xFAQ.html#attributes)
> There is a reasonable fear that attributes will be used to create language dialects.
> The recommendation is to use attributes to only control things that do not affect the meaning
> of a program but might help detect errors (e.g. [[noreturn]])
> or help optimizers (e.g. [[carries_dependency]]).

Yes, this argument was used. I’m (even) more conservative than Bjarne on this one.

People spoke up for two main different views on the question, “what does it mean to say [[attributes]] should not affect language semantics?” For convenience I’ll label these as the “weak” and “strong” views. Both views agree that if a program is valid both with and without the attribute, it should have exactly the same meaning both ways. Where the two views/camps differ is on whether it counts as “changing the meaning of the program” if a program that is valid if the attribute is ignored is rejected (fails to compile) if the attribute is observed:

  • The “weak” view says that’s okay because it didn’t really change the meaning of code that could ever execute, it just caused it to fail to compile. (I know, [[noreturn]] seems like it’s doing that… but it actually doesn’t quite meet this definition in my opinion, see below.)
  • The “strong” view, which I strongly support, says that calling a program illegal not only is the most dramatic semantic change possible, but also should be considered a nonconforming extension because it rejects code that is legal in the standard. (I know, [[noreturn]] in particular is standard… but it’s still problematic for this reason, see below.)

On principle, I do not like opening the door to let compiler writers use [[attributes]] as an excuse to not respect legal ISO C++ programs. And I say that as someone who works on a C++ compiler team and actively does C++ language extension design, and having the excuse of disabling part of ISO C++ that I don’t like by throwing in an [[attribute]] could be useful. Don’t get me wrong, there are corner cases of C++ I would like to turn off, but I try hard (and so far successfully) to refrain from doing such a thing without ISO C++’s blessing because it would break source code portability. Encouraging the view that nonstandard [[attributes]] can be a legitimate excuse to reject conforming C++ programs strikes me as putting a live grenade in a public square with a “pull me” tag on the pin. The whole point and primary benefit of having an ISO standard for C++ is to guarantee source portability; this weakens that, and for that reason I view it as a dangerous position to take.

However, in general the “weak” interpretation prevailed, and on those grounds [[noreturn]] and [[carries_dependency]] remained an attribute. I didn’t fight it because at least we got to remove [[final]], [[override]] and [[base_check]] as attributes, which was my primary concern since those would see far more use, and as long as we fixed those I was happy to say I could live with the others in order to get a consensus standard.

Post-Mortem: Assessing [[noreturn]]

Disclaimer: The following is an informational analytical exercise, not a public lobbying for a change. I support where we ended up as a whole to get C++11, it is probably too late to tweak [[noreturn]], and I consciously didn’t pursue making the following arguments at the time because [[noreturn]] (and [[carries_dependency]] are so rarely used that I can live with them, and you have to be willing to give some ground to get a consensus standard – the important thing was to get [[final]], [[override]], and [[base_check]] out and then stop while you’re ahead.

With that disclaimer in place, let me present counterarguments to show why I believe that in an ideal world [[noreturn]] shouldn’t be an attribute because it really is a keyword in [[attributes]] clothing and doesn’t actually meet either the weak or the strong view:

  • I don’t think that [[noreturn]] meets the bar set by the weak view, because it does more than just cause programs to fail to compile. In my opinion, adding [[noreturn]] does change the meaning of a conforming program, because the C++11 standard says in 7.6.3/2: “If a function f is called where f was previously declared with the noreturn attribute and f eventually returns, the behavior is undefined. … [Note: Implementations are encouraged to issue a warning if a function marked [[noreturn]] might return. —end note ]” – Even if respecting a [[noreturn]] did cause a compiler to reject some code (which is not required by the standard, and is not even mentioned even in the non-normative note which just talks about maybe issuing a warning), that means that void f(); and [[noreturn]] void f(); do not have the same semantics – returning from the first is always defined behavior (if you do it), and returning from the second is undefined behavior. This isn’t just a language-lawyerly argument either – the reason the standard says “undefined behavior” here is because that’s how the standard explicitly gives latitude to optimizers – it’s saying that “a compiler optimizer may assume the function doesn’t return, and optimize the code in ways that could cause different execution (even catch-fire semantics) if f ever actually does return.” Telling the compiler it may rely on this attribute to have meaning is, to me, clearly giving the attribute a language meaning and so changes the program’s semantics if it is present. So I don’t think it’s actually true that the presence of [[noreturn]] doesn’t affect language semantics.
  • It also doesn’t meet the strong view and discourages portability, by opening the door for using nonstandard attributes as a reason to reject conforming code. Now, it’s true that [[noreturn]] is in the standard itself, and so we might be tempted to say it’s not like a nonstandard attribute in this way that reduces portability, but it is – you cannot reliably write portable C++11 code under the assumption that [[noreturn]] has no semantic meaning and can be ignored. That’s because adding [[noreturn]] really does change the meaning of a function declaration (by adding guarantees that the optimizer can use, as described above) and so you really need to treat it as though it were a language keyword – because it is, just dressed in [[attributes]] clothing.

So in my view [[noreturn]] is a keyword dressed in [[attributes]] clothing.

Having said all that, experts do disagree, and the two camps have simply had to agree to disagree on this question – we got unanimous consensus on the standard, even though [[noreturn]] and [[carries_dependency]] are a bit of a sore point, because everyone was satisfied enough that we at least averted having [[final]], [[override]] and [[base_check]].

Reader Q&A: auto and expression templates

Motti asked:

While you’re dealing with reader’s Qs….

In your keynote in “Going Native” you mentioned that type inference should almost always be used, except for some obscure cases with expression templates.

Yes. To give people context, the idea is when declaring local variables, prefer to use auto to deduce the type. For example:

auto x = begin(v);

This seems like a rather serious wart on the language,

It’s a wart, but I don’t know about “serious” – it doesn’t come up that often. Still, your question is quite apropos:

part of the power of expression templates (to my understanding) is that they can be dropped in by a library implementer and thus improve the clients’ code without their knowledge.

Was there any discussion to allow type authors to opt-out of type inference? (e.g. by allowing an “operator auto()”). If this wasn’t discussed for C++11 is it being discussed for C++1y?

Yes, and even exactly that spelling has been suggested. I’ll take that as a +1 for discoverability if we name it that!

(For people reading this comment, if it doesn’t make any sense I wrote about it last year in my blog http://lanzkron.wordpress.com/2011/02/21/inferring-too-much/)

Reader Q&A: When will better JITs save managed code?

In the comments on last week’s interview, MichaelTK asked:

@Herb: You mentioned two things I don’t fully understand in your talk.

1) Why would C++ be a better choice for very large scale applications than NET/Java? I mean the zero abstraction penalty (which is more a JIT compiler issue and not intrinsically hardwired into C#) , okay, but besides that?

2) C++ really only has a few language features which actually let you write faster code in theory. In practice, JIT compilers are just not good enough, yet, to fully optimize on C++ pace and that’s one of the main reasons why C++ excels at efficiency.

No, the reasons go deeper than that. I’m actually giving a talk at Lang.NEXT on Wednesday which focuses exactly on the managed/native divide. I’ll post a link next week.

In the meantime, short answer: C++ and managed languages make different fundamental tradeoffs that opt for either performance or productivity when they are in tension.

Why does Microsoft not put effort into a static C++ like compiler for C#/NET, say in manner of NGen, so that C# actually has even the slightest chance of being competitive with C++?

Actually, Microsoft has been actively investing in that for over a decade. So have Java vendors. I expect those efforts to continue.

Otherwise, saying C++ is more efficient than C# is not a theoretical issue, but caused by bad JIT compilers.

This is a 199x/200x meme that’s hard to kill – “just wait for the next generation of (JIT or static) compilers and then managed languages will be as efficient.” Yes, I fully expect C# and Java compilers to keep improving – both JIT and NGEN-like static compilers. But no, they won’t erase the efficiency difference with native code, for two reasons.

First, JIT compilation isn’t the main issue. The root cause is much more fundamental: Managed languages made deliberate design tradeoffs to optimize for programmer productivity even when that was fundamentally in tension with, and at the expense of, performance efficiency. (This is the opposite of C++, which has added a lot of productivity-oriented features like auto and lambdas in the latest standard, but never at the expense of performance efficiency.) In particular, managed languages chose to incur costs even for programs that don’t need or use a given feature; the major examples are assumption/reliance on always-on or default-on garbage collection, a virtual machine runtime, and metadata. But there are other examples; for instance, managed apps are built around virtual functions as the default, whereas C++ apps are built around inlined functions as the default, and an ounce of inlining prevention is worth a pound of devirtualization optimization cure.

Second, even if JIT were the only big issue, a JIT can never be as good as a regular optimizing compiler because a JIT compiler is in the business of being fast, not in the business of generating optimal code. Yes, JITters can target the user’s actual hardware and theoretically take advantage of a specific instruction set and such, but at best that’s a theoretical advantage of NGEN approaches (specifically, installation-time compilation), not JIT, because a JIT has no time to take much advantage of that knowledge, or do much of anything besides translation and code gen.

More in the talk on Wednesday (for those who are at the conference) which will go live online next week… I’ll blog about it when it’s up.

Reader Q&A: Keywords and Attributes

Referring to C++ AMP, a reader emailed me to ask:

Are you going to replace restrict keyword with new C++11 attribute feature [[]] ?

No, because restrict is a language feature and [[attributes]] are specifically designed to be ignorable and shouldn’t be used for things having language semantic meaning. During the ISO C++11 process, I was heavily involved in a long battle to try to prevent keywords dressed in [[attributes]] clothing from sneaking into the standard; for example, C++11 final and override used to be [[final]] and [[override]] in pre-final* drafts and I led the charge against that, and with the help of likeminded people it was overturned.

 

* pun intended

Interview: C++–A Language for Modern Times

imageLast week I spent 30 minutes with interviewer Robert Hess to talk about the differences between managed and native languages, and why modern C++ is clean, safe, and fast – as “clean and safe” as any other modern language, and still the king of “fast.”

The interview just went live today on Channel 9. Here’s the blurb from the site:

C++: A Language for Modern Times

C++ has been around for what seems like forever. It might seem like it’s taken a back seat to languages that provide better application isolation and better development throughput, but in truth it remains one of the most widely used languages in the world. In order to gain some better insights on how C++ measures up in a "managed" world, I’ve invited Herb Sutter, Program Manager for Visual Studio, to explain how C++ has evolved and how it remains a great choice for many modern day development tasks.

I’ve said some of these things before, but it’s important to get the word out – modern C++11 is not your daddy’s C++, and as people return more and more to C++, we have some work still to do to help people unlearn some negative things that are no longer true (and in some cases never were true) about C++ as we know and use it today.

C++ and Beyond 2012: Aug 5-8, Asheville, NC, USA

imageFebruary and March have been killer busy, so that I forgot to repeat an important announcement here: registration is open for C++ and Beyond 2012! I’m looking forward to teaching for three days again with Scott Meyers and Andrei Alexandrescu at one of the top C++ conference highlights of the year.

This year, C&B will be held on August 5-8 in beautiful Asheville, North Carolina, USA. Registration is limited to 120 people, and now that I’m a month late in repeating this announcement I see that it’s already over 25% booked… seats are going faster than in either of the previous years, but fortunately there are still lots of spaces available as I write this.

This is becoming yet another big year for C++ in the industry, as C++ use and interest continues to surge and even the ISO C++ committee isn’t slowing down after delivering C++11 but is actually accelerating, ramping up work for the next round on concurrency/parallelism, networking, filesystem, and other short-term topics of interest as mentioned in my trip report. As usual, C++ and Beyond will feature the most important material you can use today and information about what to expect that’s coming down the pike short-term tomorrow.

Only two of the session descriptions have been posted so far, but they’re already deeply interesting and brand-new material never presented before – by us or by anyone, as far as I’m aware. Here they are…

1. “Universal References in C++11” (brand-new talk by Scott Meyers)

Scott’s first-announced talk on “Universal References in C++11” targets a key underpinning of two C++11 marquee features – move semantics and perfect forwarding. I’ve seen drafts of the material, and this is going to be a deeply illuminating talk that covers not only the “what” and “how” of thinking about and effectively using T&& declarations in C++, but also the “why” – the thinking behind the language rules that helps us to understand the reasons why this important C++11 feature was designed the way it is, and what other topics and techniques it affects.

2. “You Don’t Know [keyword] and [keyword]” (brand-new talk by Herb Sutter)

Yes, the title really is “You Don’t Know [keyword] and [keyword],” at least for now. Here’s the description I just posted:

I plan to give a brand-new talk for the first time at C&B, but I’m conflicted regarding what to say about it here because it’s recently been a bit of a startling realization to me about C++11, and I think it may be a bit startling for others too. I don’t want to be a tease, but I also want to save it as a surprise for C&B itself.

In the meantime, here’s a teaser…

In addition to the many new C++11 features that everyone’s listing, it has dawned on me over the winter that there’s actually another major change that isn’t being talked about anywhere, or even being listed as a change in C++11 at all as far as I know, because I and other key experts and committee members I’ve asked didn’t fully realize that we altered the basic meaning of not one but two fundamental keywords in C++. It’s a change that has profound consequences, that rewrites and/or invalidates several pieces of pre-C++11 design guidance, and that’s directly related to writing solid code in a concurrent and parallel world. This isn’t just an academic change, either – everyone is going to have to learn and apply the new C++11 guidance that we’ll cover in this session.

I plan to talk about it first at C&B, in a session tentatively titled as above – I’ll fill in the keywords later. You may already guess a few keyword candidates based on the description above, and here’s a final hint: You’ll hardly find two C++ keywords that are older, or whose meanings are more changed from C++98 to C++11. (No, they aren’t auto and register.)

I hope you can come, and I’m looking forward to seeing many of you in Asheville this summer.

Trip Report: February 2012 C++ Standards Meeting

wg21The spring 2012 meeting of ISO/IEC JTC1/SC22/WG21 (C++) was held on February 6-10 in Kona, Hawaii, USA.

Here’s the major takeaway: This is going to be a busy year as investment in C++ across the industry continues to increase, and that’s good news for C++.

Here are some highlights from the meeting.

Attendance

This was the second meeting after completion of the C++11 standard. After a standard ships, often attendance will decline for a while, especially if the intent is to “go quiet” for a time to let the industry catch up, as we did after completing C++98.

As you can see below, however, it’s clear that this time the C++ committee is gearing up, not gearing down, after shipping its latest major standard. That’s reflected in record attendance: 73 experts attended, with record numbers of participants from companies like Google and Intel and Microsoft and NVidia, to avidly begin planning for work on the next standard as well as other deliverables even in advance of the next standard.

Full speed ahead, part 1: C++1y

The biggest decision we knew would be discussed was to decide “what’s next” after C++11. Right away on Monday morning we decided that WG21 will immediately begin working on a new revision of the ISO C++ standard, including both language and library extensions, with a rough target of completing work on a new “C++1y” standard in approximately five years. That is, y is hoped to be approximately 7, but that’s intended to be only a rough scope guide at this point.

To have any chance of making y be approximately 7, C++1y can add at most one major new language feature, and there are already more language extension proposals than could possibly fit. The evolution working group (EWG), chaired as usual by Bjarne Stroustrup, therefore spent much of the week surveying the landscape of major evolution proposals we might consider in this round, and we had initial presentations of several, ranging from concurrency and parallelism to modules and static if.

We tried not to make any yes/no scope decisions at this meeting, and so many of these will come up again as updated and further-refined proposals at our next full meeting in October; at that point we intend to start saying yes and no to particular proposals we want to consider for the C++1y timeframe. In the interim, some of the proposals (notably concurrency/parallelism approaches, and the module system proposals) have enough interest that subgroups will hold additional smaller face-to-face meetings this summer in between full WG21 meetings so as to make more progress in these areas; more on this below.

Full speed ahead, part 2: Libraries galore

As I reported form our last meeting, the library working group (LWG) also has already decided to immediately continue working on new extensions to the standard library, and solicited proposals. In Kona, we reaffirmed that the door is open for library extensions, and our LWG chair Alisdair Meredith issued this call for library proposals.

But these libraries aren’t just for C++1y, because the LWG intends to work on shipping new libraries in smaller pieces in order to deliver work sooner and in smaller bites. Some libraries, such as File System and Networking, are big enough and separable enough to work on as independent pieces that can even ship separately from (read: earlier than) C++1y in the form of a Technical Specification (TS). (Terminology note: TS is the new ISO term for what we used to call Type 2 Technical Reports (TR), such as the first Library Extensions TR.)

These smaller pieces will be worked on independently, and once they’re ready to bring to the full WG21 LWG it will be the LWG that decides how to progress them – as part of the C++1y International Standard (IS) or as their own standalone TS or even IS.

Study Groups

Because we’re gearing up for all this work, and so much of its parallelizable, I’ve created the first four official WG21 Study Groups (SGs) that can meet independently to progress their work between full WG21 meetings. These SGs will help to refine and progress proposals faster by working on their own, but will bring all proposals to WG21 as usual for approval and further refinement before anything is published as a TS or IS.

The first four study groups, and their chairs, are as follows:

  • SG1: Concurrency and Parallelism (Hans Boehm)
  • SG2: Modules (Doug Gregor)
  • SG3: File System (Beman Dawes)
  • SG4: Networking (Kyle Kloepper)

There will be at least one face-to-face SG meeting, and there may be more. Here’s what I know about so far:

  • Week of May 7, 2012: Bellevue, WA, USA (SG1 and SG4)
  • (if needed) Summer 2012: Toronto, Canada (SG1)

Looking forward

Besides smaller Study Group meetings, here are the planned dates and locations for upcoming meetings of the full ISO C++ standards committee:

“Welcome to the Jungle” in Kansas City – March 20, 2012

WelcomeThanks to Perceptive Software who are bringing me to Kansas City in two weeks to give a free talk on “Welcome to the Jungle.”

The talk will be based on my recent essay of the same name (sequel to ”The Free Lunch Is Over”) concerning the turn to mainstream heterogeneous distributed computing and the end of Moore’s Law, with ample time for Q&A and discussion.

Here are the coordinates:

Computing Trends with Herb Sutter: Welcome to the Jungle

When: Tuesday, March 20 at 1:00 – 3:00 P.M.

Where: Boulevard Brewery, 2501 Southwest Blvd, Kansas City, MO, USA 64108

Abstract: In the twilight of Moore’s Law, the transitions to multicore processors, GPU computing, and HaaS cloud computing are not separate trends, but aspects of a single trend – mainstream computers from desktops to ‘smartphones’ are being permanently transformed into heterogeneous supercomputer clusters. Henceforth, a single compute-intensive application will need to harness different kinds of cores, in immense numbers, to get its job done. – The free lunch is over. Now welcome to the hardware jungle.

This is a free lecture; all are invited, but you should register to make sure you’ll have a seat. Note that this talk is live only and is not being recorded or webcast.

I look forward to meeting many of you there in person.