Getting Started with Modules in C++

Visual Studio 2015 Update 1 shipped with experimental support for a module system for C++. You can learn about it from this talk given by Gabriel Dos Reis at CppCon. Creating and consuming modules is very simple, but getting started with the compiler is not that obvious. At least it wasn’t very obvious to me, so here’s a quick introduction to get you started.

Start by creating an interface source file:

C:\modules>type dog.ixx

#include <stdio.h>

module dog;

export namespace dog
{
    void woof()
    {
        printf("woof!\n");
    }
}

You can use an extension other than .ixx but then you need to tell the compiler that this is the interface to your module. Anything included before the module declaration is not part of the module’s interface but rather merely an implementation detail. So this module will export the dog namespace and its woof function. Nothing else. Go ahead and compile it as follows:

C:\modules>cl -experimental:module -c dog.ixx

Notice the module switch enables support for modules, much like the await switch enables support for coroutines. And since we’re not building an executable, the -c switch instructs the compiler not to involve the linker just yet. The compiler dutifully emits the module artifacts:

C:\modules>dir /b dog.*
dog.ifc
dog.ixx
dog.obj

The .ifc file contains the metadata for the module. The compiler also produces an .obj file that is used to link the module to produce an executable. I can now write an app that relies on this module:

C:\modules>type app.cpp

import dog;

int main()
{
    dog::woof();
}

The import directive tells the compiler to look for the dog module and the main function can call the woof method without having to include any additional declarations. That’s pretty awesome! Compiling the app is also quite straitghtforward:

C:\modules>cl -experimental:module app.cpp dog.obj

The compiler, with the help of the linker this time, successfully imports, compiles, and links the application:

C:\modules>dir /b app.*
app.cpp
app.exe
app.obj

The app prints woof:

C:\modules>app.exe
woof!

There are a variety of other compiler switches to control search paths and other defaults, but this should get you started with modules in Visual C++ 2015 Update 1. Enjoy!

Update: The Visual C++ team just posted a more detailed description.

Microsoft + Kenny + Modern C++ for the Windows Runtime

I am happy to announce that I have joined forces with Microsoft to improve the C++ experience on Windows. I will be joining the Windows team in Redmond later this month to begin work on the future of Modern C++ for the Windows Runtime. I will also be working closely with members of the Visual C++ team to ensure the best possible experience for C++ developers on the Windows platform. Thanks to everyone for your support and encouragement as I worked on the Modern project. The future of C++ on Windows is looking up!

A Windows Runtime ABI for Modern C++

Given some Windows Runtime type like Windows.UI.Core’s CoreWindow, you have the option to call its methods in the most natural way thanks to Modern C++ for the Windows Runtime:

using namespace Windows::UI::Core;
CoreWindow window = CoreWindow::GetForCurrentThread();

window.Activate();

The Activate method is a modern C++ projection of the underlying ABI call that the operating system expects, but because Modern is a library-based language projection you can easily call the underlying ABI directly simply by using the -> operator to reach down to the underlying interface pointer. What might be a little surprising is that the following won’t compile:

CoreWindow window = CoreWindow::GetForCurrentThread();

HRESULT hr = window->Activate();
// error C2039: 'Activate': is not a member of ...

That’s because there is no such method on the ABI interface. The method is actually called abi_Activate so you need to write the statement as follows:

HRESULT hr = window->abi_Activate();

Now why is that? That’s certainly not how the Windows SDK defines the ICoreWindow ABI.

The Modern compiler generates its own ABI so that’s not a problem, but why does it do that? Well there’s the actual reason and then there’s another good reason that Martyn Lovell came up with during a recent conversation while I was trying to explain my reason. I’ll start with his. :)

Developers approaching the modern C++ language projection without a good understanding of modern C++ may not realize why object->Method is any different to object.Method. Indeed, given all the prior art thanks to C++/CX they could be forgiven for thinking that object->Method is the preferred approach. So had window->Activate compiled, they may not immediately realize the mistake (and the lack of error handling). On the other hand, forcing the developer to choose between window.Activate and window->abi_Activate makes the choice far more obvious. We might say that this is the design of least surprise.

OK, so that’s a good reason and I hadn’t thought of that. Now here’s the real reason. It is very difficult to project the Windows Runtime efficiently into standard C++ in a compile-time manner. Everything about the Modern language projection depends on compile-time type information to produce the fastest possible implementation that adds no run-time overhead. Now a language projection must deal with two rather disparate sets of abstractions. There are those involving binary COM interfaces that must be projected into C++, such as the ICoreWindow interface that is projected as the CoreWindow class. Then there are those involving C++ constructs like classes or lambdas that must be transported back through the runtime as COM interfaces. It is this latter camp where the trouble arises.

When implementing ABI interfaces in modern C++ it’s rather important that they be implemented to satisfy the vtable while also being projected into modern C++ without any additional overhead. Consider the IFrameworkViewSource interface as defined by the Windows SDK. I might need to implement both the virtual functions to satisfy the ABI as well as the modern implementation in the same class. This works reasonably well and might look something like this:

#include <windows.applicationmodel.core.h>
namespace abi = ABI::Windows::ApplicationModel::Core;

struct IFrameworkView {};

struct FrameworkViewSource : Implements<abi::IFrameworkViewSource>
{
    // ABI implementation ...
    virtual HRESULT __stdcall CreateView(abi::IFrameworkView ** view) noexcept override
    {
        // ...
        *view = detach(CreateView());
        // ...
    }

    // Modern implementation ...
    IFrameworkView CreateView()
    {
        // ...
    }
};

Incidentally, Implements is a variadic class template that implements both IUnknown and IInspectable and is included in the Modern library. Anyway, the compiler is happy and the implementation is clean and efficient. I then move on to the IFrameworkView interface and try to do the same thing and all of a sudden I have a problem:

struct FrameworkView : Implements<abi::IFrameworkView>
{
    // ABI implementation ...
    virtual HRESULT __stdcall Run() noexcept override
    {
        // ...
        Run();
        // ...
    }

    // Modern implementation ...
    void Run()
    {
        // ...
    }
};

The FrameworkView class suddenly has two methods with the same name lacking any parameters and thus the ABI’s virtual function and the modern projection differ only by return type and other factors that don’t affect overload resolution. This won’t compile. I would now have to tear apart the implementation to separate the vtable methods from the modern implementation and this adds additional complexity and run-time cost.

Instead, the Modern compiler produces an ABI for the Windows API that avoids the problem. It goes further and produces class templates employing the curiously recurring template pattern (CRTP) to implement the ABI while leaving a modern implementation up to the developer:

template <typename T>
struct IFrameworkViewT : Implements<IFrameworkView>
{
    // ...

    virtual HRESULT __stdcall abi_Run() noexcept override
    {
        return call([&]
        {
            static_cast<T *>(this)->Run();
        });
    }

    // ...
};

The app developer then doesn’t have to think about virtual functions and ABIs and can simply write a Run method in modern C++:

struct FrameworkView : IFrameworkViewT<FrameworkView>
{
    void Run()
    {
        using namespace Windows::UI::Core;

        CoreWindow window = CoreWindow::GetForCurrentThread();
        window.Activate();

        CoreDispatcher dispatcher = window.Dispatcher();
        dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
    }
};

This same technique is used to power Windows Runtime components. The Modern compiler produces a modern projection of a component’s runtime classes that a developer would work on, but it also produces base class templates that implement all of the ABI virtual functions while delegating to a modern implementation.

Incidentally, the Modern compiler produced its own ABI long before I solved this problem with the abi_ preamble. It did so because the ABI provided by the Windows SDK is unnecessarily large due to the way the MIDL compiler produces definitions for both C and C++. The Modern ABI is much smaller and thus precompiles a whole lot quicker.

Now here’s another design question for you to ponder: why do the Modern library’s helper functions, such as call and detach above, start with a lower case letter when the convention for everything else mirrors that of the Windows Runtime? Shouldn’t they also start with an uppercase letter? Until next time, check out Modern C++ for the Windows Runtime!

Windows Runtime Internals

My new course about the internals of the Windows Runtime is now available from Pluralsight!

Windows Runtime Internals

Discover the compilers, tools, mechanics, and abstractions that make up the Windows Runtime’s component architecture.

This course will help you understand how the class-based component abstraction presented by Windows Runtime language projections is actually implemented in terms of traditional COM interfaces. You will learn all about the tools and compilers that are necessary to build rich components entirely with Standard C++ in the most efficient manner. You will discover how abstractions like constructors and static methods are implemented with activation factories. You will learn how delegates and events are actually implemented with COM interfaces and lock-free algorithms. And you will discover the weird and wonderful way that the Windows Runtime uses C++ templates to simulate CLR generics using parameterized interfaces.

This is my first advanced level course for Pluralsight and not for the faint-hearted. Enjoy!

Windows Runtime Components

Welcome to a new series in MSDN Magazine exploring the essentials and internals of the Windows Runtime. You can read the first installment right now in the July 2015 issue:

Windows Runtime Components

Over the next few months I’m going to explore the essentials of the Windows Runtime. The purpose is to break down the higher-level abstractions that developers use in the various language projections and toolchains in order to examine how the Windows Runtime works at the application binary interface (ABI)—the boundary between applications and the binary components they rely on to access OS services.

Many thanks to Larry Osterman for his feedback on this series.

What does it mean to be constexpr complete?

Yesterday Stephan Lavavej announced on the Visual C++ blog that their compiler would be constexpr complete for the Visual Studio 2015 build that is released to manufacturing. While that sounds exciting – and it is – I don’t think many developers really know what that means and may make certain reasonable assumptions about what is achievable at compile time. Stephan alluded to a difference between the original goals and aspirations for constexpr in the earlier C++11 standard compared to what is found in the newer C++14 standard. So what does this mean?

The original notion of a generalized constant expression is careful to limit the definition to sufficiently simple functions. That meant that such functions could not contain local variables, iteration statements, or selection statements. Such restrictions quickly became onerous and were lifted in C++14. I’m not a language lawyer so I’ll just give you an illustration. Imagine I need to count the occurrences of some character within a string. I would naturally like to express this at compile time as follows:

static_assert(Count("a % b % c % d") == 3, "fail");

With Visual Studio 2015, I need to be careful to implement the Count constexpr function to avoid using any of the aforementioned constructs. This is a reasonably simple problem so it doesn’t take a great leap of the imagination to write a simple recursive function:

constexpr unsigned Count(char const * const string)
{
    return *string == '\0' ? 0 : (*string == '%') + Count(string + 1);
}

While this is a recursive function, the recursion happens at compile time. In fact, the compiler may choose to unroll or transform the implementation to avoid recursion. From what I can tell, the Visual C++ compiler does not attempt to transform this so if I have a very large string then it will hit the compiler’s call-depth limit. Fortunately, this can be avoided with a compiler option. On the other hand, recursion is clearly not ideal and writing such contrived expressions quickly becomes error prone to say the least. The C++14 definition of constexpr functions makes it possible to write this function with more of the C++ language at my disposal:

constexpr unsigned Count(char const * string)
{
    unsigned count = 0;

    for (; *string != '\0'; ++string)
    {
        count += *string == '%';
    }

    return count;
}

Notice that I’m able to manually transform the recursive function with an iteration statement and use a local variable to keep track of the count. I am even able to increment the pointer. While this is a simple example and there’s nothing wrong with the recursive example above (unless I have very large strings) it sure is handy to be able to have the expressive power of C++14 constexpr functions at my fingertips.