C++20: Module Support of the Big Three

C++20: Module Support of the Big Three

This post is a cross-post from www.ModernesCpp.com.

I have written almost 100 posts about C++20 in the last four years, but I’m not done. This post continues my story about C++20.

Modules are one of the Big Four in C++20. In my C++20 classes, they are one of the main topics. Sadly, the implementation in GCC and Clang was way behind the Microsoft Compiler. Consequentially, I usually used the Microsoft Compiler in my classes, my talks, and books to present modules. I’m happy to say that the module support of GCC and Clang significantly improved. I will, therefore, present the current module implementation state (10/2023) of the Big Three GCC, Clang, and MSVC in this post.

If you are not familiar with modules in C++20, here is a simple example:

A Simple Module

This is the module math.

// math1.ixx

module;                  // (1)          

#include <numeric>
#include <vector>

export module math;      // (2) 

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

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

The global module fragment starts with the keyword module (line 1) and ends with the exporting module declaration (line 3). The global module fragment is the place to use preprocessor directives such as #include so that the module can compile. Preprocessor entities used inside the global module fragment are only visible inside the module. The module math exports the two functions add and getProduct.

 The client imports the module math (line 1) and uses its functionality:

// client1.cpp

#include <iostream>
#include <vector>

import math;                        // (1)

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

Finally, this is the output of the program:

Article content


 

Article content

Modernes C++ Mentoring

Be part of my mentoring programs:

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

 

Of course, there is a lot more to modules you should know. I suggest that you read the following posts:

  1. The Advantages of Modules
  2. A Simple math Modul
  3. Module Interface Unit and Module Implementation Unit
  4. Structure Modules
  5. Open Questions to Modules
  6. Private Module Fragment and Header Units

I started with a simple module, and I will make it even more simple when I discuss the module implementation state of GCC, Clang, and MSVC.

Implementation State

math.ixx defines the module math, I will use it in the following comparison.

// math.ixx

export module math;     // (1)

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

Additionally, here is the client program client.cpp importing the module math.

// client.cpp

import math;       // (2)

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

Line (1) is the exporting module declaration, and line (2) imports the module. For obvious reasons, I will not show you the program’s output.

First, you may wonder why I called the module declaration file math.ixx. Here is the first irritating point.

Module Declaration File

  • The Microsoft compiler uses the extension ixx. The suffix ixx stands for a module interface source.
  • The Clang compiler uses the extension cppm. The m in the suffix probably stands for module.
  • The GCC compiler uses no special extension.

These are only the defaults that you can change. Now, let me compile and use the module math.

Compile and Use the Module

First, I start with Microsofts cl.exe 19.29.30133 for x64 compiler.

Microsoft Compiler

Article content

These are the steps to compile and use the module with the Microsoft compiler. I only show the minimal command line. As promised, more will follow in the next post. Additionally, with an older Microsoft compiler, you must use the flag /std:c++latest instead of the flag /std:c++20.

cl.exe /std:c++20 /c math.ixx           
cl.exe /std:c++20 client.cpp math.obj
        

* Line 1 creates an obj file math.obj and an IFC file math.ifc. The IFC is the module and contains the metadata description of the module interface. The binary format of the IFC is modeled after the Internal Program Representation by Gabriel Dos Reis and Bjarne Stroustrup.

* Line 2 creates the executable client.exe. The compiler implicitly finds the compiled math.ifc from the first step.

Article content

Now, let’s continue with the Clang compiler

Clang Compiler

I use the Clang 16.0.5 compiler.

Article content

The Clang compiler expects a module with the extension cppm. Consequently, I must rename the math.ixx file to math.cppm. On the contrary, the file client.cpp is unchanged. Finally, here are the corresponding build and use steps:

clang++ -std=c++20 -c math.cppm --precompile -o math.pcm
clang++ -std=c++20 client.cpp -fprebuilt-module-path=. math.pcm -o client.exe
        

  • Line 1 creates the module math.pcm. The suffix pcm stands for precompiled module and is equivalent to the ifc file extension of the  Microsoft Visual Compiler. Additionally, the produced module already includes the module definition. Consequentially, the Clang compiler does not produce an object file math.o. The option --precompile is necessary for creating the precompiled module.
  • Line 2 creates the executable client.exe, which uses the module math.pcm. The Clang compiler requires that you specify the path to the module with the -fprebuilt-module-path flag. If not, the link process fails:

Article content

Finally, let me do it with the GCC compiler.

GCC Compiler

I use the GCC 11.1.0 compiler.

Article content

The GCC Compiler neither expected Window’s ixx nor Clang’s cppm suffix. Consequently, I rename the math.ixx file into a cpp file: math.cxx. The client.cpp is identical to the one I used with the Microsoft and the Clang compiler.

g++ -c -std=c++20 -fmodules-ts math.cxx
g++ -std=c++20 -fmodules-ts client.cpp math.o -o client
        

  • Line 1 creates the module math.gcm and the object file math.o. I have to specify -fmodules-ts. The extension –fmodules-ts irritates me because ts usually stands for technical specification. The module math.gcm is in the subdirectory gcm.cache. math.gcm is the compiled module interface. Presumably, gcm stands for GCC compiled module.
  • Line 2 creates the executable client. It uses the module math.gcm implicitly.

What’s Next?

This post gave you the first steps of how to build a module with the Big Three. In my next post, I will drill deeper.


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, 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, Rob North, Bhavith C Achar, and Marco Parri Empoli.

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

My special thanks to Embarcadero, PVS-Studio, Tipi.build, and Take Up Code.

Seminars

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

Bookable

German

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++

New

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

Contact Me


Article content
Modernes C++ Mentoring



To view or add a comment, sign in

More articles by Rainer Grimm

  • Charity run for ALS

    Tomorrow, on the 28th, there will be a charity run for ALS in Rottenburg. The course is exactly 1 km long.

    2 Comments
  • Small Safety Improvements in the C++ 26 Core Language

    Safety is an important concern in C++26. Contracts are probably the most important feature for safety.

    1 Comment
  • My ALS Journey (30/n): Cippi at the CppCon

    This week was very exciting for Cippi. She visited CppCon in Aurora, near Denver.

    2 Comments
  • Contracts: Evaluation Semantic

    After briefly presenting the details of contracts in my last article, “Contracts: A Deep Dive“, I would like to take a…

  • My ALS Journey (29/n): I feel Good

    I often receive messages asking about my health and wishing me well. I am very happy to receive these messages and just…

    5 Comments
  • Contracts: A Deep Dive

    August 25, 2025/in C++26/by Rainer GrimmI already introduced contracts in the article “Contracts in C++26”. In this…

  • My ALS Journey (28/n): Bureaucracy – The German Disease

    Today I want to write about a sad topic. Bureaucracy in the German healthcare system is becoming increasingly absurd.

    2 Comments
  • Data-Parallel Types: Algorithms

    The data-parallel types library has four special algorithms for SIMD vectors. The four special algorithms are min, max,…

  • My ALS Journey (27/n): An Emergency Call

    Firstly, I would like to say that I am doing very well and have made a full recovery from my incident. However, I would…

    8 Comments
  • Data-Parallel Types: Reduction

    In this article, I will discuss reduction and mask reduction for data-parallel types. Reduction A reduction reduces the…

Others also viewed

Explore content categories