Visual C++ Q&A

In a comment on another blog entry, "Dev" asked:

When are the Visual C++ team going to make some big announcements on the new C++ features coming after Visual C++ 2008. I know you are very active in the new C++0x world, but people are really worried about what MS is doing or not doing with VC++ on windows, and the VC team seems to be ever shrinking to the point people are questioning if C++ on windows is even going to be a lead product for all the things we would like to use it for, but MS has been unwilling/able to tool us up to do, from XAML to web services. We could really use you speaking up now for our needs, and MS’s product plan to help with our unrest. Can you announce something soon?

This question actually has two parts. Breaking it down:

Q1: Is VC++ doing major work to keep VC++ a lead product and support XAML and other cool new stuff?

Yes, there are significant announced and unannounced things in the pipeline. Here’s a link to one good Channel 9 video by two of our senior VC++-ers, and its associated blurb:

Steve Teixeira and Bill Dunlap: Visual C++ Today and Tomorrow

How will VC++ evolve? How has the advent of managed code affected the evolutionary trajectory of VC++? What’s the VC++ team up to these days, anyway? How much time are they spending innovating C++, the native language? Tune in and learn first hand from two people who know the answers to the above questions (and much more); Steve Teixeira, Group Program Manager, and Bill Dunlap, Program Manager. If you want to know where Visual C++ is heading, then you definitely want to watch this interview. If you are a C++ developer, the message should be very loud and clear: Microsoft has not forgotten about you!

Q2: How about some news and announcements?

Dev asked about post-VC++ 2008 news, but let me point out VC++ 2008-related news too.

A great place to subscribe for news like this is the Visual C++ team blog. Here are some recent highlights that relate to the above:

July 27, 2007 Visual Studio 2008 (Orcas) Beta 2 Now Available. This includes a public beta of our next release, Visual C++ 2008.
May 31, 2007 MSDN article: “An Inside Look At The Next Generation Of Visual C++”. Covers some Visual C++ 2008 features, including enhancements to MFC, targeting Vista, and managed/native interop.
April 10, 2007 Visual C++ Orcas Feature Specifications online. Enjoy! Many of you will no doubt like /MP — parallel builds.

(I probably shouldn’t say this, but I just can’t help myself: /MP is actually already there in VC++ 2007, and I use it all the time myself — on a 2-core machine the compile phase goes nearly 2x faster, but there’s not much difference in the link phase. We just didn’t document it because we didn’t have time to fit-and-finish it, and if you try it you will find rough edges. For example, you may see oddly interleaved build messages in the output window, and if you Ctrl-Break a build you may need to do a full rebuild next time. You Have Been Warned. But have fun experimenting, and just don’t tell anyone I told you…)

Quoting from the last article, here are some more resources:

There are also some channel 9 videos on some of these new features (and other aspects of the work we are currently doing):

What about post-VC++ 2008 news? There will be other announcements in the coming months, because we have major stuff in the pipeline that may eclipse (no pun intended) even the above cool features. As those start to make their way out into the public eye, I hope you’ll find them as refreshing as I do.

The Pit and the Pendulum

Don’t fall into the pit of thinking there’s no pendulum, or that the pendulum can be nailed to one side.

Earlier today, Michael Swaine wrote an article commenting on the "trend" of Google Gears, Adobe AIR, and Microsoft Silverlight. Here’s the opening blurb and intro paragraph:

Return of the Desktop

Is the rediscovery of the desktop just the latest swing of some tech-trend pendulum, or is there something more going on here?

This year, some of the big boys gave every impression of having suddenly and simultaneously remembered that there is such a thing as a desktop. Google got Geared up, Adobe announced AIR, and Microsoft saw the light with Silverlight, all of which are tools to help web developers integrate operations on the Web and the desktop just a little better. That oft-repeated mantra that the web browser is the new operating system? In 2007, not so much.

Of course it’s a pendulum. More specifically, it’s the industry constantly rebalancing the mix of several key technology factors, notably:

  • computation capacity available on the edge (from motes and phones through to laptops and desktops) and in the center (from small and large servers through to local and global datacenters)
  • communication bandwidth, latency, cost, availability, and reliability

This balancing actually isn’t news; we’ve been doing it since the dawn of computing. Conceptually, it’s not much different from how the designers of your PC balanced the kind and speed of memory to match the speed of the processor and the bus and the hard drive etc. to create a balanced system. We do and redo this exercise all the time. Here are just a few of the pendulum swings we’ve seen historically:

Era/Epoch The Center The Edge
Precambrian ENIAC
Cambrian Walk-up mainframes
Devonian Terminals and time-sharing
Permian Minicomputers
Triassic Microcomputers, personal computers
Jurassic File and print servers
Cretaceous Client/Server, server tier Client/Server, middle tier
Paleocene PDA
Eocene Web servers
Oligocene ActiveX, JavaScript
PDA phone
Miocene E-tailers
Pliocene Flash, AJAX
Pleistocene Web services
Data centers
Holocene Google Gears
Adobe AIR
Silverlight

How many pendulum swings can you count on just that list? In my own career, I’ve missed only the Precambrian and Cambrian (I’m a child of terminals and micros, and never had to carry stacks of punched cards uphill both ways in snow up to my waist). Many of you have experienced most of these swings.

It’s also not news that neither the center nor the edge is going to go away. We’re in an expanding computing universe: The question is not whether one will replace the other, but what balance they will be in at a given point. This will continue to be true for the foreseeable future no matter how often people on either end of the pendulum swing try to nail the pendulum where they want it for their own business reasons. (Take it from someone who lived through trying to market early peer-to-peer database and application models in the midst of Larry Ellison’s screaming-loud "network computer" hype, and had to deal with VC after VC who believed desktops and notebooks were going to evaporate. Sigh.)

The Computing Pendulum (slide from Craig Mundie's talk)What is news, of course, is how those factors are changing and therefore how their balance is changing. Craig Mundie has spoken about this pendulum in several talks this year, including last week’s Financial Analysts Meeting (transcript and WMP webcast link; slides, including the one reproduced at right).

Quoting from one of those talks:

One of the things that I also find fascinating at this point in time is how people, how easily we forget about the cyclical nature of the evolution of the computing paradigm.

And from another:

Right now, as the Internet has evolved, broadband has become more highly penetrated, and to some extent the computers seems to be not fully utilized, we’re in the middle of one of these natural pendulum like swings between centralized computing and computing at the edge. It started with the mainframe, and then we added terminals, and then we moved to departmental, and then we moved to personal; it just kind of moves back and forth. And there are a lot of people today who say, oh, you know, I think that in the future we’ll just have dumb presentation devices again, and we’ll do all the computing in the cloud.

But … I contend that since the cloud is made ultimately from the same microprocessors, as the utilization becomes higher, it becomes impractical for a whole variety of costs and latency reasons to think you can just push everything up the wire into some centralized computing utility.

And so, in fact, I think for the first time in a long time we’re going to see the pendulum come into a fairly balanced position where we, in fact, do have incredible power plants of the Internet in these huge datacenters that provide these integrating services across the network, but at the same time we’re going to see increasingly powerful local personal computing facilities in everything from embedded devices, cell phones, and on up the computing spectrum.

A nicely balanced view. The center (mainframes, datacenters) isn’t going away anytime soon. But neither is the edge (PDAs, laptops). It would obviously be foolish to imagine either away, at least yet, because they each have different capability, availability, performance, and reliability characteristics, so there’s plenty of reason to choose each one for a different part of an application or system.

Don’t fall into the pit of assuming the pendulum will get nailed to one side. That’s pretty unlikely. Bet on new technologies constantly being developed to bring the center and the edge into new balance by filling the holes where each is deficient and as the center and edge grow at different rates. Yesterday’s disconnected computers just couldn’t do everything you can on an Internet — so as internetworks became mainstream something like HTML and AJAX had to come to let us exploit them. Early and current web apps just can’t do everything you can on a rich client — hence first AJAX, then Gears, AIR, and Silverlight, with more still to come tomorrow and next year and next decade.

Fasten your seat belts.

Machine Architecture Talk at NWCPP in September

For anyone who’s interested and in the Pacific Northwest area, I’ll be giving a talk at NWCPP on September 19. Without giving too much away, I can tell you it will feature everything from a real rocket launch (well, on video) to a Roman chariot race (well, actually, sort of a simulation of a chariot race involving arrays, lists, and sets):

Machine Architecture: Things Your Programming Language Never Told You

High-level languages insulate the programmer from the machine. That’s a wonderful thing — except when it obscures the answers to the fundamental questions of “What does the program do?” and “How much does it cost?”

The C++/C#/Java programmer is less insulated than most, and still we find that programmers are consistently surprised at what simple code actually does and how expensive it can be — not because of any complexity of a language, but because of being unaware of the complexity of the machine on which the program actually runs.

This talk examines the “real meanings” and “true costs” of the code we write and run especially on commodity and server systems, by delving into the performance effects of bandwidth vs. latency limitations, the ever-deepening memory hierarchy, the changing costs arising from the hardware concurrency explosion,
memory model effects all the way from the compiler to the CPU to the chipset to the cache, and more — and what you can do about them.

See the NWCPP website for more details as the date gets closer.

NWCPP meetings are open and free-as-in-beer, so come one and come all, but note that some nights the room tends to fill up quickly so it can be worth being a little early to be sure of having an actual seat. NWCPP are currently meeting on the Microsoft campus in Building 41, which happens to be the building I work in, and so unfortunately none of my usual excuses for being late will work and I’ll have to show up on time…

C++ Video Podcasts with Bjarne

While at Stroustrup & Sutter #3, Bjarne and I took some time out to be interviewed by Ted Neward on behalf of the OnSoftware series from our mutual publisher Addison Wesley. We were only half-serious when we asked Ted to turn his I Love C# shirt inside out, but he did it — what a sport!

Two 10-minute video podcasts have been published so far:

  • Design and Evolution of C++: Talking about C++98, C++0x, and related topics including concurrency.
  • High Performance Applications with C++: Resuming with concurrency, HOPL, and enabling more than any one person could imagine in advance.

I’m told that these were in the top 25 of all tech podcasts in early July. Wow.

Here’s where you can find them:

  • Now at iTunes: Search Podcasts for Stroustrup, or click here to subscribe to OnSoftware video podcasts or here to subscribe to audio podcasts.
  • (Workaround) Now through OnSoftware Video RSS: In MP4 format, if you don’t do iTunes and have an MP4 viewer.
  • Soon at InformIT: To escape the iTunes and MP4 tyrannies, watch this homepage to see when they go up. I’m told InformIT will be self-hosting the podcasts sometime in the next week or two.

Andy Koenig’s C++ Blog, and Parrots

I recently discovered that Andy Koenig has a blog on DDJ (recommended). For those keeping score at home, Andy is one of the folks that Scott Meyers named as his "most important C++ people ever" last year. Andy is #2 (in chronological order), after Bjarne Stroustrup of course.

On a whimsically related note, I also recently had the pleasure of watching the engaging documentary The Wild Parrots of Telegraph Hill (also recommended). I mention it here because the main subject, Mark Bittner, reminds me a lot of Andy. Mark talks very much like Andy, and he even looks a little similar. I apologize in advance to those who think any similarity is all in my head, especially if they’re Mark (or Judy) or Andy (or Barb).

For the attention-span-challenged, I-can’t-wait-for-Netflix generation (which sometimes admittedly includes me, sigh), you can watch an interview of Mark and Judy here along with a few other related videos.

[Updated to add the chronological order note.]

Name Lookup Uses the Static Type

I recently received the following question in email from Vijay Visana. I’ve slightly edited it for brevity and/or flow. Vijay writes:

While tinkering with multiple-inheritance in C++ I have come across one peculiarity that baffled me a lot.

A derived (multiple inheritance – no virtual base class) class having all pure abstract base classes can have multiple copies of a distant base class embedded in it and can call that class’s methods without ambiguity.

In Figure 1, C implements all the Pure ABC methods of all the above pure Abstract Base Classes. When I call method of C as following

C* p = new C;
p->Method_of_A(); // though it has two ways to reach A no ambiguity

Let’s pause here for a moment: Do you see why there’s no ambiguity? And did you notice the interesting tidbit of information in the brief description of C’s implementation?

But let’s read on and see the rest of the question:

Now in Figure 2 I twist the pure ABC hierarchy to introduce a closer path. Here C again implements all the Pure ABC methods of all the above pure Abstract Base Classes. When I call method of C as following

B4* p = new C;
p->Method_of_A();

At this point of time compiler (vc++) finds it ambiguous. I have seen that an adjustor thunk is being created (when I remove this dubious method call and debug it) for it. Virtual inheritance can solve the problem but I want to know just out of plain curiosity to understand the implementation of MI in C++ (or rather in VC++).

Okay, let’s look into this.

The difference in behavior has nothing to do with the complexity of the inheritance hierarchy or with vtables or thunking. Rather, it has to do with name lookup (in this case, finding "Method_of_A") which in turn has to do whether the static type of the object has the function you want, or whether the compiler has to look further (into base classes) to find the name.

Here’s a quick recap of what happens when we write a function call in C++:

  • First comes name lookup: The compiler looks around to find a function having the requested name. It starts in the current scope (in these cases, the scope of the class we’re calling the member function on) and makes a "candidate list" of all functions having that name; if the list is empty, it goes outward to the next enclosing scope (e.g., namespace or base class) and repeats. If it makes it all the way out to the global scope and still finds no candidates, sorry Charlie, you get "name not found."As soon as a scope is encountered that has at least one function with the requested name, the compiler goes to step two.
  • Second comes overload resolution: If the candidate list has more than one function in it, the compiler attempts to find a unique best match based on the argument and parameter types. If two or more functions are equally good (or bad) matches, sorry Charlie, you get "ambiguous call."
  • Third comes accessibility checking: Finally, the compiler looks to see whether you may actually call the function (e.g., that it’s not private). If you don’t have clearance to call the function, sorry Charlie, you’re not calling from within a derived class, a member function, or friend function and you should have thought of that before trying to access an inaccessible protected or private function. For shame.

I’ve written more about this in my books and articles. Here are a few that are online:

All three steps consider only the static type of the object. Here’s the key interesting information that makes the first example work:

In Figure 1, C implements all the Pure ABC methods of all the above pure Abstract Base Classes.

In other words, there is a function C::Method_of_A. So when the reader did this

C* p = new C;
p->Method_of_A(); // though it has two ways to reach A no ambiguity

the comment is really a red herring because name lookup is not reaching up to A at all. Rather, this code is invoking C::Method_of_A directly.

The second example is needlessly complex, but the key here is that the most-derived class is still the one actually implementing the overrides, but now B4 doesn’t. So when we do this:

B4* p = new C;
p->Method_of_A();

we’re using the object as a B4 and trying to invoke B4::Method_of_A, but since B4 doesn’t provide one itself, name lookup starts looking up through the base classes and finds two equal candidates that it can’t resolve using overload resolution, and so the call is ambiguous.

Name lookup is done based on the static type of the object, or the "type that we’re using it as right now," not on its dynamic type, or the type it really is (the two happen to be the same in Figure 1, and different in Figure 2, which contributed to the confusion). In Figure 1, the static type of the object p points to is C, because p has type pointer to C (as opposed to, say, pointer to some base of C). In Figure 2, the static type is B4, which does not implement Method_of_A and so name lookup goes off into the tree of base classes, finds equal candidates that have identical signatures and so aren’t distinguishable by overload resolution, and the call is ambiguous — irrespective of the fact that the object’s dynamic type happens to be C which uniquely implements Method_of_A. We’re using it as a B4, and so a B4 it shall be… for name lookup purposes, at any rate.

Talks online about C++0x

Today, someone asked me if I was going to give a talk anytime soon about C++0x, the next C++ standard. I’ve blogged about it before, notably here. But I haven’t yet prepared a talk about C++0x as a whole — in the meantime, I pointed that person to the following talks, and I thought other people might enjoy knowing about them too. They’re all by experts who are active standards committee members participating in the evolution of C++, and at least one of the names is probably familiar:

Entitlement Week

According to McNews (this one and that one) this must be Entitlement Week… two examples (emphasis mine):
Wow; there must be something in the water. How did we teach people to feel they are owed so many things, from serious things like license to break the law without consequences, to trivial things like a right to have someone else’s creation suit their whims?
Maybe we need an unreality check.
[*] I’ve never watched The Sopranos and don’t know anything about the show. I watch TV only occasionally, and when I do I generally prefer fare like Dog Whisperer and an occasional Jeopardy.

Trip Report: April 2007 ISO C++ Standards Meeting

The ISO C++ standards committee met on April 15-20, 2007 in Oxford, UK. Despite unseasonably sunny and warm weather and good European beer (the best I tried was Budweiser, and no, I’m not kidding because it’s not the American one), we made good progress toward our goal of having a complete draft of C++09 out for public review this year.

(Aside: I delayed posting this article until the post-meeting mailing was online on the ISO C++ website, so that I could add live public links to the referenced documents, for your viewing pleasure.)

New Language Features Voted Into (Draft) C++09

The following new features progressed to the point of being voted into the draft standard at this meeting. I’ve included a link to the final paper number so that you can read up on the gory details of your favorite proposal. (Note that I’m not mentioning changes that are smaller or are just reformulations that have no effect on the semantics of your code, such as that we replaced the wording about sequence points in the standard while maintaining the same effect.)

Template aliases (aka typedef templates, generalized typedefs) [N2258]

This proposal was coauthored by Gabriel Dos Reis and Bjarne Stroustrup. I’ve written before (here in an article and here in a committee proposal) about why you might want to be able to write a typedef that nails down some, but not all, template parameters. The example from the first article is:

// Not legal C++, but it would be nice…
//
template<typename T>
typedef std::map<std::string, T> Registry;

// If only we could do the above, we could then write things like:
//
Registry<Employee> employeeRoster;
Registry<void (*)(int)> callbacks;
Registry<ClassFactory*> factories;

What C++09 actually added was not only the equivalent of typedef templates, but something more general. Template aliases allow you to get the same effect as the above using the following syntax:

// Legal in C++00
//
template<typename T>
using Registry = std::map<std::string, T>;

// Now these all work as intended
//
Registry<Employee> employeeRoster;
Registry<void (*)(int)> callbacks;
Registry<ClassFactory*> factories;

An example from the second article is motivated by making policy-based-designed templates more usable. Referring to one form of Andrei’s SmartPtr template, I showed that we can write the following wrap-the-typedef-in-a-struct workaround today:

// Today’s workaround
//
template<typename T>
struct shared_ptr {
typedef Loki::SmartPtr<
    T, // note that T still varies, but everything else is fixed
    RefCounted, NoChecking, false, PointsToOneObject, SingleThreaded, SimplePointer<T>
  >
type;
};

shared_ptr<int>::type p;   // sample usage, “::Type” is ugly

One of the primary reasons (but not the only one) why policy-based smart pointers didn’t make it into C++09 was usability: Although Loki::SmartPtr can express shared_ptr easily as just one of its configurations, the user has to type lots of weird stuff for the policy parameters that is hard to completely hide behind a simple typedef, and so the user would be less inclined to use the feature:

shared_ptr<int>::type p; // the best usability we could provide for a policy-based Shared Ptr
shared_ptr<int> p; // what actually won and is now in C++09

Too bad we didn’t have template aliases then, because now we could have our cake and eat it too:

// Legal in C++09
//
template<typename T>
using shared_ptr =
    Loki::SmartPtr<
      T,
      RefCounted, NoChecking, false, PointsToOneObject, SingleThreaded, SimplePointer<T>
    >;

shared_ptr<int> p;   // using the alias lets us have a completely natural syntax

This aliasing feature extends beyond templates and is also essentially a generalized replacement for typedef. For example:

// Legal C++98 and C++09
//
typedef int Size;
typedef void (*handler_t)( int );

// Legal C++09
//
using Size = int;
using handler_t = void (*)( int );

Especially for such function pointer types, the new form of "using" is simpler than typedef and lets programmers avoid playing guess-where-the-typedef-name-goes because of the C declaration syntax weirdness, at least in this place.

Variadic templates (aka "type varargs" for templates) [N2242; see N2087 for a more readable description and rationale]

This proposal was coauthored by Doug Gregor, Jaakko Järvi, Jens Maurer, and Jason Merrill.

You know how you can call a function like printf with a variable argument list (C’s good old varargs)? Well, there are times you’d like to do that for template arguments lists, too, and now you can. For example, today the C++09 tuple type needs to be declared with some fixed number of defaulted parameters:

// Drawn from draft C++09, before variadic templates
// (when the best tool we had was to hardcode some defaulted parameters)
//
template<
  class T1 = unspecified ,
  class T2 = unspecified ,
  … ,
  class TN = unspecified
> class tuple;

template<class T1, class T2, …, class TN>
tuple<V1, V2, …, VN> make_tuple( const T1&, const T2& , …, const TN& );

These declarations gets uglier as N gets bigger. And what if you want more than N types? Sorry, Charlie; the implementer just has to write enough types to cover most use cases, and the actual number in the current wording would be nonportable in practice as every implementer has to make their own choice about how many types will be enough.

With variadic templates, we can write it much more simply and flexibly (and portably, once compilers implement the feature):

// Simplified version using variadic templates
// (now in the latest working draft of C++09; see Library section below)
//
template<class… Types> class tuple;

template<class… Types>
tuple<VTypes…> make_tuple( Types&… );

This is simpler to define, works with any number of types, and will work portably no matter how many types you use. What’s not to like?

For another example that summarizes other ways to use the feature with class types, consider this example provided by Jonathan Caves (thanks, Jon!):

// Legal in C++09

template<typename… M
ixins
>
class X : public Mixins…{
public:
  X( const Mixins&… mixins ) : Mixins(mixins)… { }
};

class A { };
class B { };
class C { };

X<A, B, C> x;

For the type X<A,B,C>, the compiler will generate something like the following:

class X<A, B, C> : public A, public B, public C {
public:
  X( A const& __a, B const& __b, C const& __c ) : A(__a), B(__b), C(__c) { }
};

Unicode characters and strings [N2249]

This proposal was written by Lawrence Crowl, based on the ISO C technical report containing similar non-normative extensions for C.

C++ has essentially airlifted in the unofficial C extensions for char16_t and char32_t, and made them available in the new header <cuchar>. Here are a few basic uses:

char16_t* str16 = u"some 16-bit string value";
char32_t* str32 = U"some 32-bit string value";

C++ did a few small things differently from C. In particular, C++ requires the the encoding be UTF, and C++ is making these types a normative (required) part of its language standard.

New Library Features Voted Into (Draft) C++09

As usual, as we vote in language extensions, the library working group continues systematically updating the standard library to make use of those extensions. In particular, this time the library got support for:

  • Variadic templates (see above, including its application to std::tuple)
  • Unicode characters (see above)
  • Rvalue references (see next)

Rvalue references, aka "move construction/assignment," are a useful way to express that you’re constructing or assigning from an object that will no longer be used for anything else — including, for example, a temporary object — and so you can often get a decent performance boost by simply stealing the guts of the other object instead of making a potentially expensive deep copy. For example, move assignment for a string would simply take over the internal state of the source string using just a few pointer/integer assignments, and not perform any allocations. For more details, see this motivational paper which describes the significant performance and usability advantages of move semantics. Updating the standard library to use move semantics included notably updating the containers, iterators, and algorithms to support moveable types, as well as deprecating auto_ptr (wow!) and replacing it with a unique_ptr that expresses unique ownership semantics. (Previously, the library had already added shared_ptr and weak_ptr to express shared ownership and shared observation semantics, so reference-counted shared pointers are already covered.)

If you’re interested in the standardese details of the new move semantics support in the standard library, you can find details of the updates in the following papers: N1856 (basic concepts, pair, and unique_ptr), N1857 (strings), N1858 (containers), N1859 (iterators), N1860 (algorithms), N1861 (valarray), and N1862 (iostreams).

There were a few other housekeeping updates, but for template metaprogramming aficionados one highlight will be the std::enable_if type trait. Have you ever wanted to write a function template that gets completely ignored for types the template wasn’t designed to be used with (as opposed to accidentally becoming a best match and hiding some other function the user really intended to call)? If you’re a template library writer and haven’t yet seen enable_if, see here for a nice Boosty discussion, and you might get to love it too.

Next Meetings

Here are the next meetings of the ISO C++ standards committee, with links to meeting information. The meetings are public, and if you’re in the area please feel free to drop by.

Note that the latter is the meeting at which we are hoping to vote out the first complete draft of the new C++ standard, and it runs straight through to Saturday afternoon. So let me insert a caveat for those who might be thinking, "oh yeah, that sounds like the meeting I think I’ll pick to attend, and catch some rays, ha ha" — having a standards meeting in Hawaii sounds nice, but it’s not nearly what you might think. If you come and want to participate, expect to be shut in windowless rooms all day, and frequently all evening — you’ll only actually see the local landscape if you fly in early or stay late, not during the meeting. But we’ll appreciate your help proofreading mind-numbing swathes of the standard!