Microsoft’s C++ compiler has an implementation of C++ module partitions, which does not conform to the C++ standard, as described in my previous blog posting.

We’re now using the non-standard partitions of the MSVC compiler for our UML Editor as explained in the rest of this blog posting.

Please note that the following code examples are not compliant with the current C++ standard. As such they can be seen as erroneous, but they satisfy the current implementation of the MSVC compiler.

Removing all existing uses of /internalPartition

I first removed all existing uses of the MSVC compiler option /internalPartition and added export at the beginning of the file like this:

// A/Foo.ixx
export module A:Foo;

struct S
{
    int a;
    int b;
};

This is now an interface partition, but it doesn’t export anything. It is intended for use inside module A only. No declarations in that partition will be directly usable outside of module A.

Even though that partition is marked as export, we do not export import the partition in the primary interface of the module A.

Note that files having export module at the beginning, must have the file extension .ixx.

Marking all implementation files with the name of the partition

Implementation files of modules usually start with:

// file A/A.cpp
module A;

This implies that the whole primary interface (or simply: The interface) of A is implicitly imported.

This is inconvenient if we want to implement the functions that are declared in a specific partition.

Let’s say we have an interface partition Bar of module A:

// A/Bar.ixx
export module A:Bar;

export void hello();

Partition Bar is export imported in the primary interface of module A:

// file A/A.ixx
export module A;

export import :Bar;

If we want to implement function hello, we could do it like this:

// file A/Bar.cpp
module A;

void hello()
{
    ...
}

This would be conformant to the C++ standard, but it has the drawback that the whole primary interface of module A is implicitly imported, which has the consequence that if any interface partition of A is changed, that file needs to be recompiled.

The MSVC compiler enables to instead do the following:

// file A/Bar.cpp
module A:Bar;

void hello()
{
    ...
}

With that, the MSVC compiler implicitly imports the external partition Bar (instead of the whole interface of A, as before).

The MSVC compiler also allows to have multiple files with the same:

module A:Bar;

at the beginning. We can thus implement functions of partition Bar in one or more cpp files.

All these cpp files only (implicitly) import the interface partition Bar, so these files are only recompiled if A/Bar.ixx changes.

(last edited 2026-03-23)