7 comments

[ 0.22 ms ] story [ 26.0 ms ] thread
It doesn't really change much, name clashes are already an existing danger that can bite you at any moment you download somebody else's code from the Internet. Definitely not something unique to C++ modules and not an argument against them
C++ modules seem like one of those things worth staying far, far away from. I wish they worked well because it would be a huge boon to modernizing C++. But from what I've seen, it's a dumpster fire. The spec is too broad and ill-defined. The compilers have gone to herculean lengths to implement it regardless, and MSVC is the only compiler with full support (for a C++20 feature, mind you). [0]

Libraries aren't implementing it. There's no `cargo`-like tooling for installing modules (AFAIK).

Can the C++ committee revert or refine the modules spec? Has anything like that been done before?

[0]: https://arewemodulesyet.org/tools/

If names must be unique, shouldn't there be a way to resolve conflicts by renaming the modules?

For example, if we use libraries A and B and both want to define module "foo", straightforward compiler options passed when compiling their sources could make the undisciplined libraries produce instead, in the context of our project, modules fooA and fooB and accordingly consume fooA or fooB (found in our project's module stash) where they reference their own module "foo", as if the replacement names had been used in export and import clauses.

Are module names completely erased from actually compiled libraries and executables? What complications am I missing?

IMO module names should be the same as the namespace of objects exported by the module (more like Modula-2). I've never used C++20, but modules do seem a bit of a mess.

Globally unique namespace names are needed to be able to differentiate the same name used in multiple namespaces, but of course are potentially a problem if you don't have control over them.

It might occasionally be useful if there was a workaround to resolve namespace clashes by doing something like:

namespace foo {

#include "foo/module.h" // namespace Module

using Module; // Module.x is now foo.x

}

namespace bar {

#include bar/module.h" // namespace Module

using Module; // Module.x is now bar.x

}

Or, we could invent a new syntax like "import foo/module as foo".

But AFAIK there is no way to then tell the linker to rename symbols to match (e.g. -l foo/module.o as foo -l bar/module.o as bar).

> But AFAIK there is no way to then tell the linker to rename symbols to match (e.g. -l foo/module.o as foo -l bar/module.o as bar).

Renaming symbols is done with objcopy. From objcopy(1):

    --redefine-sym old=new
           Change the name of a symbol old, to new.  This can be useful when
           one is trying link two things together for which you have no
           source, and there are name collisions.
It seems for me that adding modules into C++ was a mistake. The old-style approach with includes wasn't ideal, but it was well understood and all its downsides and pitfalls were well known.

Than modules were standardized and this happened in a very strange way. Usually major features are already implemented at least in some compilers before being standardized, but with modules it wasn't the case. It was in 2020, it's now 2025 and they aren't fully implemented and tested in all major compilers and it's unclear how long one need to wait to be able to use them.

Modules are also very problematic, as the article above shows. They didn't solve many C++ problems with multiple translation units management, like compilation speed. Moreover they added new problems atop of old ones. And managing dependencies may become ever more painful, because some dependencies use old-style includes and some use modules instead (xkcd 927).

From comments in the blog post

>This is not a goal. Module files are essentially better PCH, they are not meant to be a stable artifact. Consumers compile the module files from the library's interface files as needed.

That's not what I was expecting (since I haven't looked into modules too carefully). Seems counterintuitive. Today I can download an external library's pre-built artifacts and link them as long as they are compiled with the same compiler family for my architecture, etc.

This seems to mean you can't import pre-compiled modules of such a library.

OTOH, for large game projects you also want to compile third-party libs from source at least once to make sure you don't end up in the wrong branch of the debug/release/x64/x86/DLL/static maze.

So maybe it's a non-issue for most projects. You get the code, compile it once and store the artifact for future use.

Still seems a bit restrictive to me. I would have expected modules to be like DLL/.so so you could use them at your own peril if you wanted to do something quick/dirty.