MSVC: C++20 modules that import each other fail to compile

1k Views Asked by At

Support for C++20 modules has been recently added in MSVC 16.8. If I'm not mistaken, one of the advantages of using modules is that circular import dependencies are now supported. However, the following test project still fails to compile in the latest version of the Microsoft compiler.

computer.ixx

export module computer;

import printer;

export struct Computer {
    Printer* printer;
};

printer.ixx

export module printer;

import computer;

export struct Printer {
    Computer* computer;
};

main.cpp

import computer;
import printer;

int main() {
    Computer* c = new Computer();
    Printer* p = new Printer();
    p->computer = c;
    c->printer = p;
}

Trying to compile this code results in: MultiToolTask has encounted an issue scheduling task because one or more tasks still remains but none could be started. Please check the inputs and their dependency to avoid cirular loops. (typos reproduced verbatim) and confuses IntelliSense, hanging or even crashing Visual Studio.

I've also tried inverting the order of the import and export lines, which didn't fix the problem.

I know this is still a beta-ish feature, but I want to make sure my assumptions are correct (that this code should work) and if there's anything wrong in the code that I should change for it to work.

If you want to try this yourself, you can find a MSVC project containing the above code here: https://github.com/albertvaka/ModulesTest

1

There are 1 best solutions below

2
On BEST ANSWER

If I'm not mistaken, one of the advantages of using modules is that circular import dependencies are now supported.

I am not aware of any version of module proposals, standards, or implementations that has ever supported circular dependencies. In pretty much every version of modules as a concept, going back to even pre-C++11 iterations, the module dependency graph has always been required to be a directed, acyclic graph.

It doesn't even make sense how that would work. If you import a module, then by definition, you need that module to be compiled before you can compile the module that imports it. But if that module requires your module too, there's no order in which to compile your modules. And you can't just "kinda" compile a module now and wait for something else to show up to fill in the gaps or something. C++ just doesn't work that way.