Logo
Articles Compilers Libraries Books MiniBooklets Assembly C++ Rust Go Linux CPU Others Videos
Advertisement

Article by Ayman Alheraki on July 10 2026 02:43 AM

Finally C++20 Modules Work End-to-End with GCC 16.1 on Windows 11

Finally: C++20 Modules Work End-to-End with GCC 16.1 on Windows 11

Download the winlibs Version : https://github.com/brechtsanders/winlibs_mingw/releases/download/16.1.0posix-14.0.0-ucrt-r3/winlibs-x86_64-posix-seh-gcc-16.1.0-mingw-w64ucrt-14.0.0-r3.zip

After years of waiting, testing, partial implementations, unusual compiler switches, and inconsistent behavior across platforms, I can finally confirm that a complete basic C++20 named-module workflow works successfully with GCC 16.1 on Windows 11.

By “complete workflow,” I mean that GCC successfully performed every essential stage:

  1. Compiled a module interface unit.

  2. Generated the Compiled Module Interface file.

  3. Compiled another translation unit that imported the module.

  4. Linked the generated object files.

  5. Produced a native Windows executable.

  6. Ran the program and returned the expected results.

This is an important practical milestone for programmers who use GCC and MinGW-w64 on Windows.

The Test Environment

The test was performed on Windows 11 using this compiler:

This configuration means:

  • GCC 16.1.0

  • 64-bit x86-64 target

  • MinGW-w64

  • Microsoft Universal C Runtime, or UCRT

  • POSIX threading model

  • Structured Exception Handling, or SEH

  • WinLibs release 2

WinLibs provides standalone GCC and MinGW-w64 distributions for Windows, including GCC 16.1 builds using UCRT and POSIX threads.

No Visual Studio installation was required.

No MSYS2 environment was required.

The compiler was used directly from Windows Command Prompt.

Why This Test Matters

C++ modules were standardized in C++20 to provide a modern alternative to the traditional textual inclusion model based on #include.

Instead of repeatedly copying header-file contents into translation units, modules introduce explicitly exported interfaces that compilers can process and reuse.

Their intended benefits include:

  • Better separation between interfaces and implementations.

  • Reduced dependence on preprocessor inclusion.

  • Improved isolation between libraries.

  • Potentially faster compilation in large projects.

  • Fewer macro-related conflicts.

  • More explicit dependency relationships.

GCC describes modules as a modular compilation system intended to improve build performance and library isolation.

However, module support in GCC has historically been experimental and incomplete. GCC 15 brought major improvements, and GCC 16 continues this progress.

The Module Example

The test consists of two source files:

The first file defines and exports a named module. The second imports and uses it.

Module Interface Unit: calculator.cppm

The declaration:

declares a named module called calculator.

The exported functions:

become part of the public module interface and can be used by translation units that import the module.

Unlike a conventional header file, this file is compiled as a module interface unit.

Module Consumer: main.cpp

The important line is:

There is no declaration of add() or multiply() inside main.cpp.

There is also no traditional header such as:

The compiler obtains the exported declarations from the compiled interface of the calculator module.

Building the Module on Windows 11

The two files were placed in the same directory:

Command Prompt was opened in that directory:

Old object files and module cache files were removed before compiling:

Cleaning gcm.cache is useful during testing because an old Compiled Module Interface may no longer match the current source code or compiler configuration.

Step 1: Compile the Module Interface

The module interface must be compiled before any source file that imports it:

The options mean:

Although GCC 16 uses C++20 as its default C++ language mode, module support is not enabled automatically. The -fmodules option remains necessary.

The -x c++ option was used to ensure that the .cppm file was treated as C++ source by this particular Windows toolchain.

After compilation, GCC created two important outputs:

The object file contains the compiled machine code.

The .gcm file contains GCC’s Compiled Module Interface, commonly abbreviated as CMI.

The generated module cache can be inspected with:

The presence of:

confirms that GCC recognized and compiled the file as a module interface.

Step 2: Compile the Importing Translation Unit

After the module interface was available, the consumer was compiled:

The option:

asks GCC to report information about the Compiled Module Interface that it reads.

During this stage, GCC successfully found and loaded:

This proves that the import calculator; declaration was resolved through the generated module interface rather than through a traditional header file.

The two object files were linked:

This generated a native Windows executable:

Notice that the .gcm file is not passed directly to the linker.

The CMI is needed during compilation of the importing source file. The linker works with the resulting object files:

Step 4: Run the Executable

The resulting program was executed:

The output was:

This confirms that:

  • The module interface was parsed correctly.

  • Its exported functions were compiled.

  • The CMI was generated.

  • The importing translation unit found the module.

  • Exported declarations were visible to the importer.

  • The object files linked correctly.

  • The resulting Windows executable ran successfully.

Complete Windows Command Sequence

The entire test can be repeated using these commands:

Expected output:

What Has Been Proven?

This test proves that basic named C++20 modules work end-to-end with GCC 16.1 on Windows 11 using a 64-bit WinLibs MinGW-w64 UCRT toolchain.

The following features were tested successfully:

FeatureResult
Module declarationSuccessful
Exported functionsSuccessful
.cppm module interfaceSuccessful
CMI generationSuccessful
gcm.cache creationSuccessful
Module importSuccessful
Separate compilationSuccessful
Object-file generationSuccessful
Windows linkingSuccessful
Native executable generationSuccessful
Runtime executionSuccessful

This was not merely a syntax test.

It was a complete compile-import-link-run test.

An Important Qualification

It would be inaccurate to conclude from this example that every part of the C++ module specification is now completely implemented.

GCC’s own documentation still states that its module support is not complete, and the GCC 16 release notes continue to classify C++20 module support as experimental.

Advanced projects may still encounter limitations involving areas such as:

  • Private module fragments.

  • Complex module partitions.

  • Header units.

  • Large dependency graphs.

  • Build-system dependency discovery.

  • Cross-compiler CMI portability.

  • Interaction with macros and legacy headers.

  • Mixing modules with complicated template libraries.

  • Automatic module build ordering.

A CMI generated by one compiler should also be treated as compiler-specific build output rather than as a portable binary library interface.

Therefore, the accurate conclusion is:

The complete basic named-module workflow works successfully with GCC 16.1 on Windows 11, but GCC’s implementation of the entire C++ modules specification remains experimental and has documented limitations.

A Major Improvement for GCC on Windows

For a long time, using C++ modules with GCC—especially on Windows—felt more like experimenting with compiler internals than using a production language feature.

Simple examples could fail because of:

  • Unsupported file extensions.

  • Missing compiler options.

  • Incorrect compilation order.

  • Stale module cache files.

  • Toolchain differences.

  • Incomplete module implementations.

  • Poor build-system integration.

With GCC 16.1, the fundamental workflow is now much clearer and more reliable:

This does not mean that header files will disappear immediately.

It does mean that GCC users on Windows can now begin realistic experiments with named modules without depending exclusively on Microsoft Visual C++.

Final Conclusion

C++20 modules have finally reached a practically usable stage for basic applications with GCC 16.1 on Windows 11.

Using a WinLibs MinGW-w64 GCC 16.1 toolchain, I successfully:

  • Created a named module.

  • Exported functions from it.

  • Generated a GCC Compiled Module Interface.

  • Imported the module from another source file.

  • Compiled both translation units separately.

  • Linked them into a Windows executable.

  • Ran the program with the correct output.

The experiment was successful from beginning to end.

The most precise declaration is therefore:

C++20 named modules now work end-to-end with GCC 16.1 on Windows 11 for the complete basic compile, import, link, and execution workflow.

This is an encouraging milestone for GCC, MinGW-w64, WinLibs, and C++ developers who prefer an open-source Windows toolchain.

The age of C++ modules on GCC for Windows has not reached complete maturity yet—but it has unquestionably moved from theory into working practice.

Advertisements

Responsive Counter
General Counter
1536930
Daily Counter
2234