C++20: Module Interface Unit and Module Implementation Unit


Thanks to the module interface unit and implementation unit, you can separate the interface from the implementation when defining a module. Let me show you how.


As promised in my last post, C++20: A Simple math Modul, I want to make a short detour on my Clang Odyssee. My detour is a compact refresher to all I wrote in the referred post.

My Clang Odyssey

First, I don't want to blame anyone but myself. Based on talks from Boris Kolpackov "Building C++ Modules" at the CppCon 2017 or Corentin Jabot "Modules are not a tooling opportunity" I had the impression that the vendors suggested the following extensions for their module definition:

  • Windows: ixx
  • Clang: cppm
  • GCC: no suggestion

In the case of the Clang compiler, I was wrong. This is my simple math module, which I tried to compile with the Clang compiler.


// math.cppm

export module math;

export int add(int fir, int sec){
    return fir + sec;


I tried to compile the module with Clang 9 and Clang 10 on Microsoft and Linux. I tried to compile it with the brand-new Clang 11 compiler, built from the sources. Here is one of my many tries. 


This command line should create the module math.pcm. I specified in the command line -std=c++20 -fmodules-ts and the error message said: module interface compilation requires '-std=c++20' or '-fmodules-ts'.  I made all variations of the two flags, added the global module fragment to the module definition, and invoked the Clang compiler with additional flags, but the result was always the same.

Then I asked Arthur O'Dwyer and Roland Bock for their help. For Arthur, modules worked fine with Clang: "Hello World with C++2a modules". Roland rebuilt its Clang 11, and it worked with my module definition.

Roland and I had the same Clang compiler and the exact module definition. I compared his command-line with mine, character by character, and I noticed something.

Mine:   clang++ -std=c++20 - -fmodules-ts -stdlib=libc++ -c math.cppm -Xclang -emit-module-interface -o math.pcm
Roland: clang++ -std=c++20 - -fmodules-ts -stdlib=libc++ -c math.cpp -Xclang -emit-module-interface -o math.pcm


Roland gave his module math.cpp cpp, and so did Arthur. Don't give your module definition the suffix cppm.

Now, compiling and using the module was straightforward.


To end this Odyssey, here is the client.cpp file and a few words to the necessary flags for the Clang command line.


// client.cpp

import math;

int main() {
   add(2000, 20);


clang++ -std=c++2a -stdlib=libc++ -c math.cpp -Xclang -emit-module-interface -o math.pcm  // (1)
clang++ -std=c++2a -stdlib=libc++ -fprebuilt-module-path=. client.cpp math.pcm -o client   // (2)


  1. Creates the module math.pcm. The suffix pcm stands for the precompiled module. The flag combination -Xclang -emit-module-interface is necessary for creating the precompiled module.
  2. Creates the executable client, which uses the module math.pcm. You have to specify the path to the module with the flag -fprebuilt-module-path.

The module math was straightforward. Let's be a bit more sophisticated.


Rainer D 6 P2 540x540Modernes C++ Mentoring

Be part of my mentoring programs:





Do you want to stay informed about my mentoring programs: Subscribe via E-Mail.

Guideline for a Module Structure

Here is the first guideline for a module structure:


module;                      // global module fragment

#include <headers for libraries not modularized so far>

export module math;          // module declartion 

import <importing of other modules> 

<non-exported declarations>  // names with only visibiliy inside the module

export namespace math {

    <exported declarations>  // exported names 



 This guideline serves two purposes. It gives you a simplified module structure and an idea of what I'm going to write about. So, what's new in this module structure?

  • You can import modules. The imported modules have module linkage and are not visible outside the module. This observation also applies to the non-exported declarations.
  • I put the exported names in namespace math, which has the same name as the module.
  • The module has only declared names. Let's write about the separation of the interface and the implementation of a module.

Module Interface Unit and Module Implementation Unit

According to the mentioned guideline, I want to refactor the final version of module math from the previous post C++20: A Simple math Modul.

Module Interface Unit


// mathInterfaceUnit.ixx


import std.core;                            

export module math;       

export namespace math {

    int add(int fir, int sec);
    int getProduct(const std::vector<int>& vec);



  • The module interface unit contains the exporting module declaration: export module math.
  • The names add, and getProduct are exported.
  • A module can have only one module interface unit.

Module Implementation Unit


// mathImplementationUnit.cpp

module math;

import std.core;

int add(int fir, int sec){
    return fir + sec;

int getProduct(const std::vector<int>& vec) {
    return std::accumulate(vec.begin(), vec.end(), 1, std::multiplies<int>());


  • The module implementation unit contains non-exporting module declarations: module math;
  • A module can have more than one module implementation unit.

Main Program


// client3.cpp

import std.core;

import math;

int main() {
    std::cout << std::endl;   
    std::cout << "math::add(2000, 20): " << math::add(2000, 20) << std::endl;
    std::vector<int> myVec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    std::cout << "math::getProduct(myVec): " << math::getProduct(myVec) << std::endl;
    std::cout << std::endl;


  •  From the user's perspective, only the namespace math was added

Building the Executable

Manually building the executable includes a few steps.


cl.exe /std:c++latest /c /experimental:module mathInterfaceUnit.ixx /EHsc /MD      // (1)
cl.exe /std:c++latest /c /experimental:module mathImplementationUnit.cpp /EHsc /MD // (2)
cl.exe /std:c++latest /c /experimental:module client3.cpp /EHsc /MD                // (3)
cl.exe client3.obj mathInterfaceUnit.obj mathImplementationUnit.obj                // (4)


  1. Creates the object file mathInterfaceUnit.obj and the module interface file math.ifc.
  2. Creates the object file mathImplementationUnit.obj.
  3. Creates the object file client3.obj.
  4. Creates the executable client3.exe.

Specify the exception handling model (/EHsc) and the multithreading library (/MD) for the Microsoft compiler.  Additionally, use the flag /std:c++latest.

Finally, here is the output of the program:


What's next?

I will extend my module math in the next post with new features. First, I import and export modules in one unit; second, I use names only visible inside the module.


Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, and Rob North.


Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, and Slavko Radman.



My special thanks to Embarcadero CBUIDER STUDIO FINAL ICONS 1024 Small


My special thanks to PVS-Studio PVC Logo


My special thanks to Tipi.build tipi.build logo


My special thanks to Take Up Code TakeUpCode 450 60



I'm happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.

Bookable (Online)


Standard Seminars (English/German)

Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.

  • C++ - The Core Language
  • C++ - The Standard Library
  • C++ - Compact
  • C++11 and C++14
  • Concurrency with Modern C++
  • Design Pattern and Architectural Pattern with C++
  • Embedded Programming with Modern C++
  • Generic Programming (Templates) with C++


  • Clean Code with Modern C++
  • C++20

Contact Me

Modernes C++,


Tags: Modules


+1 #11 Alexander 2023-01-06 05:07
Quoting learnedSloth:
Quoting Teeeeeej:
What is the motivation for splitting the interface from implementation into separate files?

Massively parallel builds maybe?

It's not really possible to do "massively parallel builds" with modules, as far as I understand, last I checked. Reason:

Any build in a modularized project must first scan through all source files, every time we build, and generate a dependency graph. Compiler does this by reading module declarations. Afterwards, the module units must be built IN ORDER, e.g. partition units before interface units. This is contrary to header/source distribution, where source files can be built an any arbitrary order, because linking happens afterwards and the header declares symbols. In module projects we don't have headers, so symbols must be declared before they can be used. Partially, the compiled binary module interface (BMI) will produce the required declarations, but definitions are still fetched during linking since we still have translation units.

I don't know if we can parallelize linking. The initial scanning should be possible to do. Modules are faster only because we don't need to compile the same header over and over again, otherwise they are actually worse for compiler performance.

Besides this, I don't see any good reason for a distinction between interface and implementation units, other than possibly the length of the interface file. I think C++ programmers are so used to the idea of having a separate file acting as "documentation" that they are creating problems for themselves. Most other languages don't have this distinction, and I consider that a good thing. Less files to read = fewer places to look = shorter code = simpler maintenance.
0 #12 LP 2023-01-23 20:41
Quoting Teeeeeej:
What is the motivation for splitting the interface from implementation into separate files? I thought part of the draw of using modules was to no longer require maintaining two files per public-facing class?

I actually brought this up with an associate who is a professional C++ dev. The major motivation, in light of the simplicity of C++ modules, is to be able to provide header files that do not the implementation. This can matter on light systems (for example, the Linux source code is about 100mb, vs 6.1mb for the headers alone). It also matters when dealing with non open-source software. You can ship a library with headers to let people link against it, without divulging your super secret implementation. This isn't such a great technical point, given that you *are* shipping the library, so a determined recepient can decompile it, but you *are* raising the cost of someone cloning your work.

It does also help with parallel builds, since dumb build systems (like GNU Make) look only at the file timestamps, and even an md5 hash of the whole file would indicate a header changed when it's really just an implementation change. You *can* still use the old precompiled header info, but you'd need a more sophisticated build system to know when it's just implementation changes vs header changes. This is also offset by the faster compile times since the compiler doesn't have to re-parse the headers repeatedly.
0 #13 Paul Topping 2023-02-01 22:03
Quoting Teeeeeej:
What is the motivation for splitting the interface from implementation into separate files? I thought part of the draw of using modules was to no longer require maintaining two files per public-facing class?

Sounds like you may be coming from a Java point of view. AFAIK, class-per-file is not a C++ custom. I've always combined related classes into a single C++ implementation file and combined declarations into headers into larger units.

The main draws of modules are faster build times and better isolation of library code from code that uses it, not necessarily in that order.

Stay Informed about my Mentoring



English Books

Course: Modern C++ Concurrency in Practice

Course: C++ Standard Library including C++14 & C++17

Course: Embedded Programming with Modern C++

Course: Generic Programming (Templates)

Course: C++ Fundamentals for Professionals

Course: The All-in-One Guide to C++20

Course: Master Software Design Patterns and Architecture in C++

Subscribe to the newsletter (+ pdf bundle)

All tags

Blog archive

Source Code


Today 3900

Yesterday 4344

Week 40778

Month 21024

All 12099233

Currently are 168 guests and no members online

Kubik-Rubik Joomla! Extensions

Latest comments