Home » C++20: Module support from the big three compilers

C++20: Module support from the big three compilers

by admin
C++20: Module support from the big three compilers

C++20: Module support from the big three compilers

Modules are one of the big four innovations in C++20. They are one of the main topics in my C++20 classes. Unfortunately, the implementation in GCC and Clang was far behind that of the Microsoft compiler. That’s why I mostly used the Microsoft Compiler to introduce modules in my classes, lectures and books. I’m happy that GCC and Clang’s module support has improved. That’s why in this article I will present the current status of module implementation (10/2023) of the big three compilers GCC, Clang and MSVC.

Advertisement

Rainer Grimm has been working as a software architect, team and training manager for many years. He enjoys writing articles on the programming languages ​​C++, Python and Haskell, but also enjoys speaking frequently at specialist conferences. On his blog Modern C++ he deals intensively with his passion C++.

Over the last four years, I’ve written almost 100 articles about C++20, but I’m not done yet. In my next article I will continue my story about C++20.

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

This is the math module.

// math1.ixx

module; // (1)

#include
#include

export module math; // (2)

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

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

The global module fragment begins with the module keyword (1) and ends with the exporting module declaration (3). The global module fragment is where preprocessor directives such as #include are used to allow the module to be compiled. Preprocessor entities used within the global module fragment are only visible within the module. The math module exports the two functions add and getProduct.

See also  AI in Software Development: Overrated

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

// client1.cpp

#include
#include

import math; // (1)

int main() {

std::cout myVec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

std::cout This is the output of the program:

More about modules can be found in the following articles:

The advantages of modulesA simple math moduleModule interface unit and module implementation unitStructuring modulesMore open questions about modulesPrivate module fragment and header units

I started with a simple module and will make it even simpler when I introduce the module implementation status of GCC, Clang and MSVC.

The Concepts introduced with C++20, along with the Ranges library, modules and coroutines, have redefined how to build modern C++ applications. From November 7th to 9th, 2023, Rainer Grimm will bring you up to date in his intensive workshop C++20: the new concepts will be comprehensively explained and will address the many useful functions that C++20 brings.

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

// math.ixx

export module math; // (1)

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

Also here is the client program client.cpp, which imports the math module.

// client.cpp

import math; // (2)

int main() {

add(2000, 20);

}

(1) is the exporting module declaration, and (2) imports the module. For obvious reasons, I’ll ignore the program’s output.

Why I named the module declaration file math.ixx might be confusing at first.

Module declaration file The Microsoft compiler uses the suffix ixx. The suffix ixx stands for a module interface file. The Clang compiler uses the suffix cppm. The m in the suffix probably stands for module. The GCC compiler does not use any special extension.

See also  Discovery of Tryptophan Molecules in Interstellar Medium near Star-Forming Regions

These are just the conventions that can be changed. Now I will compile and use the math module.

Compiling and using the module

First I’ll start with Microsoft’s cl.exe 19.29.30133 for x64 compiler.

These are the steps to compile and use the module with the Microsoft compiler. I’m just showing the minimal command line. As promised, I will write more about this in the next article. With an older Microsoft compiler, the /std:c++latest flag must be used instead of the /std:c++20 flag.

cl.exe /std:c++20 /c math.ixx cl.exe /std:c++20 client.cpp math.obj Line 1 creates an object file math.obj and an IFC file math.ifc. The IFC file is the module and contains the metadata description of the module interface. The binary format of the IFC file follows the Internal Program Representation format by Gabriel Dos Reis and Bjarne Stroustrup. Line 2 creates the executable file client.exe. The compiler implicitly finds the compiled math.ifc file from the first step.

We continue with the Clang compiler.

I’m using the Clang 16.0.5 compiler.

The Clang compiler expects a module with the cppm extension. Therefore, I will rename the file math.ixx to math.cppm. However, the client.cpp file can continue to be used unchanged. Finally, here are the relevant steps to create and use the module:

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 math.pcm module. The ending pcm stands for precompiled module and corresponds to the ifc file extension of the Microsoft Visual Compiler. In addition, the created module already contains the module definition. Consequently, the Clang compiler does not produce an object file math.o. The –precompile option is necessary to create the precompiled module. Line 2 creates the executable client.exe that uses the math.pcm module. The Clang compiler needs the path to the module: -fprebuilt-module-path. If this is not known, the link process will fail:

Finally, I use the GCC compiler.

See also  Xiaomi 13 Ultra, Leica's photography in a top smartphone

Now the GCC 11.1.0 compiler is used.

The GCC compiler does not expect the ixx suffix from Windows or the cppm suffix from Clang. So I rename the math.ixx file to a cpp file: math.cxx. The client.cpp file is identical to the one I used with the Microsoft and 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 need to specify the -fmodules-ts flag for this. The -fmodules-ts extension irritates me because ts usually stands for technical specification. The math.gcm module is located in the gcm.cache subdirectory. math.gcm is the compiled module interface. The suffix gcm probably stands for GCC compiled module. Line 2 creates the executable client. It implicitly uses the math.gcm module.

In this article I showed you the first steps on how to create a module with the Big Three. In my next article I will delve deeper into module support for the Big Three. (rme)

To home page

You may also like

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More

Privacy & Cookies Policy