Work continues on Modern C++ for the Windows Runtime as I have time to spare. I recently replaced enumerator values with literals to save over 200KB in the resulting library. Previously, I played it safe and simply used the underlying ABI for enumerator values:
enum class ApplicationExecutionState
NotRunning = ABI::Windows::ApplicationModel::Activation::ApplicationExecutionState_NotRunning,
Running = ABI::Windows::ApplicationModel::Activation::ApplicationExecutionState_Running,
Suspended = ABI::Windows::ApplicationModel::Activation::ApplicationExecutionState_Suspended,
Terminated = ABI::Windows::ApplicationModel::Activation::ApplicationExecutionState_Terminated,
ClosedByUser = ABI::Windows::ApplicationModel::Activation::ApplicationExecutionState_ClosedByUser,
The Modern compiler now simply generates enumerations as follows:
enum class ApplicationExecutionState
NotRunning = 0,
Running = 1,
Suspended = 2,
Terminated = 3,
ClosedByUser = 4,
Apart from the dramatic reduction in code size, it also benefits compile times, reduces the work required by the struggling IntelliSense compiler, and generates smaller precompiled and IntelliSense databases.
I then added an optional -debug command line option to add static_assert consistency checks, adding over 3,000 compile-time assertions. Of course, this goes beyond simply checking enumerator values. It’s not something you’ll want to enable all of the time. Instead, it’s a handy way to quickly verify whether the language projection for a new version of the Windows SDK (e.g. Windows 10) is internally consistent with the underlying ABIs.
MSDN Magazine released a special issue for Microsoft’s Connect(); event in New York City. I was asked to write a C++ feature and you can now read it online:
Visual C++ 2015 Brings Modern C++ to the Windows API
Visual C++ 2015 is the culmination of a huge effort by the C++ team to bring modern C++ to the Windows platform. Over the last few releases, Visual C++ has steadily gained a rich selection of modern C++ language and library features that together make for an absolutely amazing environment in which to build universal Windows apps and components. Visual C++ 2015 builds on the remarkable progress introduced in those earlier releases and provides a mature compiler that supports much of C++11 and a subset of C++14. You might argue about the level of completeness, but I think it’s fair to say that the compiler supports the most important language features, enabling modern C++ to usher in a new era of library development for Windows. And that really is the key. As long as the compiler supports the development of efficient and elegant libraries, developers can get on with building great apps and components.
If you like variadic templates then you’ll want to read this. It also offers a glimpse of some the techniques used to power Modern C++ for the Windows Runtime (moderncpp.com).
Folks seem to enjoy pointing out that I use printf in many of my examples of “modern C++”, as if printf is not really proper C++. Apparently, I should be using cout. The trouble is that cout isn’t exactly modern either. It has been around for as long as I can remember and it certainly doesn’t exemplify modern C++ as envisioned by C++11 and beyond. The oldest C++ textbook on my shelf was printed in 1993 and covers cout. I even posed the question to some C++ historians and they were able to date it back as far as 1989. Therefore, the argument that printf is old and cout is modern doesn’t fly. A truly modern C++ solution would also not be substantially slower than hand-written code. Most printf implementations today provide adequate type checking both at compile time and run time. Visual C++ even provides secure versions that make it quite straightforward to write defensive code quite easily with printf. Go ahead and use cout if you prefer, but don’t claim it’s the modern replacement for printf.
Here’s a slide from my 10 Practical Techniques to Power Your Visual C++ Apps course where I examine the performance of searching and sorting text. I won’t explain the numbers – you can watch the course for that – but it should be evident that cout has a serious performance problem. That analysis was done before James McNellis added some awesome modernization and performance improvements to printf in Visual C++ 2015.
Here are some resources for anyone interested in learning about I/O completion ports. I first introduced I/O completion ports in a series about parallel programming with asynchronous procedure calls (APCs):
Asynchronous Procedure Calls
Asynchronous Procedure Calls and Window Messages
Queuing Asynchronous Procedure Calls
I/O Completion Ports
I/O completion ports define a threading model for supporting scalable I/O but it is not very easy to get it right. The hardest part is thread management. Fortunately, the kernel developers responsible for operating system threads later introduced the Windows Thread Pool API. This is a very thin abstraction over I/O completion ports. This is what you should use today instead of relying on the I/O completion port functions directly. I wrote a series about the thread pool for MSDN Magazine:
C++ and the Windows API
The Windows Thread Pool and Work
The Thread Pool Environment
Thread Pool Cancellation and Cleanup
Thread Pool Synchronization
Thread Pool Timers and I/O
Naturally, any topic related to I/O and threads requires a good understanding of Windows synchronization. Here are a pair of articles that will get you up to speed:
The Evolution of Synchronization in Windows and C++
The Evolution of Threads and I/O in Windows
I also illustrate many of these techniques in my Modern C++ Concurrency course on Pluralsight.
Finally, if Microsoft needs help fixing Windows.Storage then just let me know. :)
My latest Pluralsight course is now available:
The Essentials of the Windows Runtime
This course will help you understand WinRT’s relationship to COM and how modern C++ is used to implement a class-based component abstraction on top of traditional COM interfaces.
This course introduces the Windows Runtime (WinRT), the foundational technology that underpins the future of the Windows API. You’ll learn what lies beneath the different language projections, how WinRT relates to COM and .NET, and how to implement COM and Windows Runtime classes with modern C++, Windows Runtime strings, and Windows Runtime components developed in Standard C++.
If you enjoy modern C++ you’ll want to pay special attention to the “Implementing the Windows Runtime” module where I show you how to use C++ variadic templates to implement both IUnknown and IInspectable. Watch how the compiler implements both QueryInterface and GetIids efficiently and elegantly.
Go and watch it now!
I’ve been writing a lot about DirectComposition lately. MSDN Magazine just published the final article in the series.
4. DirectComposition: Transforms and Animation
DirectComposition visuals provide a lot more than just the offset and content properties I’ve illustrated in my last few columns. The visuals really come to life when you begin to affect them with transforms and animations. In both cases, the Windows composition engine is a sort of processor and it’s up to you to calculate or construct the transform matrices, as well as the animation curves with cubic functions and sine waves.
3. DirectComposition: A Retained-Mode API to Rule Them All
2. Embracing the Windows Composition Engine
1. High-Performance Window Layering Using the Windows Composition Engine
There’s also my Pluralsight course where I dive into DirectComposition in a lot more detail.
I’ve received many requests for news on the progress of Modern – the Modern C++ Library for Windows – my new project that provides a Standard C++ language projection for the Windows Runtime along with first-class support for component development. Some folks have also offered to contribute to the library. Modern isn’t really a library as much as it is a library generator. Technically, Modern is a compiler that produces modern C++ code that may then be used to build apps and components.
I have started using it myself and am really enjoying the experience but it has a few rough edges that I need to work on before I can make it more widely available. I’m also planning to support DirectX 12, but I don’t yet have my hands on the API. As usual, the challenge is finding the time as I have other work that keeps me busy. I have lined up a handful of beta testers. Once I’ve freed up some time I hope to make a build available to them.