0

Im trying to include a module within another module, but i can't compile due to the following error:

"Cannot build the following source files because there is a cyclic dependency between them: Module1.ixx depends on Module2.ixx depends on Module1.ixx."

Code i tried:

// Module1.ixx
export module Module1;
import Module2;
export class modClass1_
{
public:
    modClass1_() {};
    ~modClass1_() {};
    int getV() { return V; };
    int getOtherModuleV() { modClass2_ mc2; return mc2.V; };
    int V = 1;
};
// Module2.ixx
export module Module2;
import Module1;
export class modClass2_
{
public:
    modClass2_() {};
    ~modClass2_() {};
    int getV() { return V; };
    int getOtherModuleV() { modClass1_ mc1; return mc1.V; };
    int V = 2;
};

Any help/suggestion will be appreciated.

Environment: Visual Studio 2019 | MSVC-2019 | C++20 | Windows 10 Pro

  • 1
    Move `getOtherModuleV` into cpp, so you can remove the needed `import`. – Jarod42 Jul 06 '21 at 12:00
  • An interdependency (if they are truly interdependent) means the two things should be together in the same module. – Eljay Jul 06 '21 at 12:59

1 Answers1

1

Create module interface units that do not have circular dependencies.

A module interface unit is somewhat similar in purpose to a header file.

A module interface unit has export module in it. The primary module interface unit has no partition name.

Remove the implementation of { modClass2_ mc2; return mc2.V; }; from export Module1; primary module interface unit, do that in the module implementation unit of Module1, and include import Module2; there.

// Module1.ixx
export module Module1;
export class modClass1_
{
public:
    modClass1_() {};
    ~modClass1_() {};
    int getV() { return V; };
    int getOtherModuleV();
    int V = 1;
};

// Module1.mxx
module Module1;
import Module2;

int modClass1_::getOtherModuleV() { modClass2_ mc2; return mc2.V; };

and the circular dependency is broken.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Thanks for the answer, this solution solves the problem of the example, but is there any other way to solve the problem by declaring the Module2 class as a Module1 variable? I updated the post with this problem. – Pedro Duarte Jul 06 '21 at 14:29
  • @PedroDuarte As a general rule, don't update questions to invalidate existing answers. Regardless, once you get that interface units are akin to headers, and implementation units akin to cpp files, the problem of breaking cyclical dependencies becomes pretty similar to how to break cyclical dependencies in traditional cpp/h file cases. You might have to create a `.forwarddecl` module in some cases, for example. – Yakk - Adam Nevraumont Jul 06 '21 at 14:37
  • @PedroDuarte Plus the code you posted doesn't compile, and fixing it results in an infinite sized class, so... If you have a true circular dependency (Foo contains a Bar, Bar contains a Foo) you have a logic error in your design, If the circular dependency can be broken (Foo contains a pointer to Bar, Bar contains a pointer to Foo) then the above technique (and extensions) fixes it. – Yakk - Adam Nevraumont Jul 06 '21 at 14:58
  • I tried the "forward declaration" method, but still dont work with the error: "[C2027]´use of undefined type 'modClass2_'". Can you give me a example? My idea is: modClass1_ contains a modClass2_ and modClass2_ contains a pointer to modClass1_. I updated the post with my idea in .h and .cpp files. – Pedro Duarte Jul 06 '21 at 15:27
  • Can you give me a example? – Pedro Duarte Jul 07 '21 at 15:52
  • @PedroDuarte I answered your original question. If you have a different question, the proper way to ask it is with the [ ask question ] button, not the [ edit ] or [ add comment ] buttons. As I aid above, don't edit questions to invalidate existing answers. – Yakk - Adam Nevraumont Jul 07 '21 at 15:55