C++ Logo


Advanced search

Re: P2581R0: Specifying the Interoperability of Binary Module Interface Files

From: Gabriel Dos Reis <gdr_at_[hidden]>
Date: Mon, 9 May 2022 17:43:20 +0000
> Yes. But the use of the term "implementation" creates a false symmetry
> with the "Module Implementation Units".


When ordinary programmers hear "interface" and "implementation", the symmetry pops up right there, and most of the time they don't arrive at the same place as us WG21 experts.
If we talk about "external", then "internal" is a natural opposite. Of course, "non-external" is another candidate, but the inevitable double negatives are best left for us, WG21 experts.

-- Gaby

-----Original Message-----
From: SG15 <sg15-bounces_at_[hidden]> On Behalf Of Daniel Ruoso via SG15
Sent: Saturday, May 7, 2022 8:45 AM
To: Iain Sandoe <iain_at_[hidden]>
Cc: Daniel Ruoso <daniel_at_[hidden]>; sg15_at_[hidden]
Subject: Re: [SG15] P2581R0: Specifying the Interoperability of Binary Module Interface Files

Em sex., 6 de mai. de 2022 ās 15:41, Iain Sandoe <iain_at_[hidden]> escreveu:
> > On 6 May 2022, at 19:55, Daniel Ruoso via SG15 <sg15_at_[hidden]> wrote:
> > 1.3. "Internal Module Partition Units": The translation units
> > with "module foo:bar"
> .. IMHO the last iteration was closer.
> The standard clearly says these are implementation units, it does not mention
> 'internal' AFAICS. They contain a partition, therefore 'partition implementation'
> (or the reverse word order, if that's concensus) seems reasonable.

Yes. But the use of the term "implementation" creates a false symmetry
with the "Module Implementation Units".

IOW, the distinction between "module Foo;" and "module Foo:Bar;" is
substantially larger than what the distinction between "Module
Implementation Unit" and "Module Implementation Partition Unit"

Specifically, a unit with "module Foo:Bar:" is still declaring things
that are not declared anywhere else and that may be imported by either
the "Primary Module Interface Unit" or by any other "Module Interface
Partition Units".

>From a practical point, a unit with "module Foo;" never generates a
bmi, while a unit with "module Foo:Bar;" always generates a bmi.

That asymmetry is even more clear when you consider that if you have
the following unit:

module Foo:Bar;
void f();

The unit that contains the definition for `f` would look like:

module Foo;
import :Bar;
void f() { ... }

So while it is true that a unit with `module Foo:Bar;` doesn't
contribute to the "external interface" of the module, it may still be
reachable by that external interface, and therefore it would need to
be distributed alongside the interface (primary and interface

Consider the following example:

export module Foo;
import :Bar;
export void g() { internal_g(); }
export void h();

module Foo:Bar;
void internal_g();
void internal_h() {};

module Foo:Baz;
void unreachable_g() {}

module Foo;
import :Bar;
import :Baz;
void h() { internal_h() };
void internal_g() { unreachable_g(); };

Maybe it would be useful to give different names for internal
partitions depending whether or not the Primary Module Interface Unit
or any Module Interface Partition Units imports that partition
(Foo:Bar vs Foo:Baz in the example above). As a partition that is
never reachable from the "external interface" doesn't need to be
distributed with the interface units, strictly speaking. But I would
argue those two types are still "Module Internal Partition Units".

>From a library design consideration, one may consider that it would be
more correct to categorize the internal partition that is only
reachable from the implementation unit to be grouped closer to the
implementation unit. However, from a tooling consideration, I would
argue the behavior of the unit in regards to how the tools have to
consider it (i.e.: generates bmi or not) takes precedence. IOW, it's
fine if the distinction between "importable" and "non-importable"
units exists only on the tooling space.

The way the distinction between reachable and unreachable internal
units would materialize in the work-in-progress CMake implementation,
for example, is that you would have different PUBLIC and PRIVATE file
sets, such that Foo:Bar would be in the PUBLIC file set, while FOO:Baz
would be in the PRIVATE file set.

SG15 mailing list

Received on 2022-05-09 17:43:23