mockingbirdnest / Principia

𝑛-Body and Extended Body Gravitation for Kerbal Space Program
MIT License
747 stars 68 forks source link

Modularization #3310

Open eggrobin opened 2 years ago

eggrobin commented 2 years ago

We have now switched to C++20; we should investigate modules to see if we can improve compilation times, and to get rid of the internal_file_name namespaces designed to hide convenience usings.

Overall, our current meow.hpp + meow_body.hpp (+ meow.cpp in some cases) should correspond to a module meow.

One could have hoped that the _body could be relegated to a module partition. Unfortunately, a look at N4868 shows that we cannot put those definitions that we had to put in headers in separate files; see below.

This means we will still have to resort to textual inclusion for the _body.hpp.

Prerequisites, which we should deal with prior to starting the great cosmic modularization:

On the unusability of module partitions

6.3 [basic.def.odr]

  1. A definition domain is a private-module-fragment or the portion of a translation unit excluding its private-module-fragment (if any). A definition of an inline function or variable shall be reachable from the end of every definition domain in which it is odr-used outside of a discarded statement.

6.6 [basic.link]

  1. A program consists of one or more translation units (5.1) linked together. A translation unit consists of a sequence of declarations.
    translation-unit:
            declaration-seqopt
            global-module-fragmentopt module-declaration declaration-seqopt private-module-fragmentopt

9.2.8 [dcl.inline]

  1. […] If a function or variable with external or module linkage is declared inline in one definition domain, an inline declaration of it shall be reachable from the end of every definition domain in which it is declared; no diagnostic is required.
  2. If an inline function or variable that is attached to a named module is declared in a definition domain, it shall be defined in that domain.

    [Note 4 : A constexpr function (9.2.6) is implicitly inline […]. — end note]

13.1 [temp.pre]

  1. A definition of a function template, member function of a class template, variable template, or static data member of a class template shall be reachable from the end of every definition domain (6.3) in which it is implicitly instantiated (13.9.2) unless the corresponding specialization is explicitly instantiated (13.9.3) in some translation unit; no diagnostic is required.
eggrobin commented 2 years ago

I think 9.2.8 7 is the only thing there which requires definition in the definition domain, as opposed to definition reachable from (the end of) the definition domain. This is weird.

eggrobin commented 2 years ago

One could have hoped that the _body could be relegated to a module partition. Unfortunately, a look at N4868 shows that we cannot put those definitions that we had to put in headers in separate files; see below.

Also, clang does not yet support module partitions.

eggrobin commented 2 years ago

10.1

7 A module is either a named module or the global module. A declaration is attached to a module as follows: (7.1) — If the declaration (7.1.1) — is a replaceable global allocation or deallocation function (17.6.3.2, 17.6.3.3), or (7.1.2) — is a namespace-definition with external linkage, or (7.1.3) — appears within a linkage-specification, it is attached to the global module. (7.2) — Otherwise, the declaration is attached to the module in whose purview it appears.

6.6

9 Two names that are the same (6.1) and that are declared in different scopes shall denote the same variable, function, type, template or namespace if (9.1) — both names have external or module linkage and are declared in declarations attached to the same module, or else both names have internal linkage and are declared in the same translation unit; and (9.2) — both names refer to members of the same namespace or to members, not by inheritance, of the same class; and (9.3) — when both names denote functions or function templates, the signatures (3.51, 3.53) are the same. If multiple declarations of the same name with external linkage would declare the same entity except that they are attached to different modules, the program is ill-formed; no diagnostic is required. 10 If a declaration would redeclare a reachable declaration attached to a different module, the program is ill-formed. […] As a consequence of these rules, all declarations of an entity are attached to the same module; the entity is said to be attached to that module.

I think this means that we cannot forward-declare things from another module.

https://stackoverflow.com/questions/67952223/c-modules-forward-declaring-entity-from-another-module seems to say as much.

This means that we cannot have inter-module friendships of templatized (and inline, constexpr, etc.) classes and functions.