C++ Logo

sg15

Advanced search

Re: unimported implementation partitions

From: Gabriel Dos Reis <gdr_at_[hidden]>
Date: Thu, 9 Jun 2022 19:55:31 +0000
Nathan -

Thanks for clarifying what you had in mind.

As data point, MSVC implements P1874 by implementing the "dependency order model". The front-end emits the dependency info, along with module ownership info to the backend/linker. And the linker uses that inform to order dynamic initialization based on dependency. This works also for OBJ archives.

Initializers for implementation partitions are treated just like any other TU in pre-C++20 world - except where they have dependencies.


Given existence of DLLs, dylibs, shared libraries, I don't know there is anything else here that can done since those units can be loaded at anytime in any order.

-- Gaby

-----Original Message-----
From: Nathan Sidwell <nathanmsidwell_at_gmail.com> On Behalf Of Nathan Sidwell
Sent: Wednesday, June 8, 2022 11:58 AM
To: Gabriel Dos Reis <gdr_at_microsoft.com>; sg15_at_lists.isocpp.org; C++ Core Language Working Group <core_at_lists.isocpp.org>
Subject: Re: [SG15] unimported implementation partitions

On 6/8/22 14:41, Gabriel Dos Reis wrote:
> Nathan -
>
> I am not sure I understand the issue. How would a program observe that an implementation partition isn't imported but is relevant to the behavior of the entire program?

Yes, it'd be a strange use, but it could be observed by the action of
its initializers:

module;
#include <stdio>
module my:secret;
int var = [](){return printf ("look at me!\n");}();

Do we make guarantees about the execution of that initializer?

>
> -- Gaby
>
> -----Original Message-----
> From: SG15 <sg15-bounces_at_[hidden]> On Behalf Of Nathan Sidwell via SG15
> Sent: Wednesday, June 8, 2022 10:23 AM
> To: C++ Core Language Working Group <core_at_lists.isocpp.org>; sg15_at_lists.isocpp.org
> Cc: Nathan Sidwell <nathan_at_acm.org>
> Subject: [SG15] unimported implementation partitions
>
> Q1) Is there a use case for implementation partitions (a non-interface
> partition) that are not imported in any module unit? How would that
> differ from a regular implementation partition?
>
> We require all interface partitions be [transitively] imported in the
> primary interface. I don't think we require implementation partitions
> be imported at least once in a program.
>
> Q2) Is there a use case for a program to include a module interface that
> is not imported in any other TU (and has no implementation units)?
>
> The reason I ask is there an ABI issue with the global initializer
> function needed for p1874. I'm going to describe it in ELF terms, but I
> imagine the same choices appear in other ABIs.
>
> 1874 is solved by having each module primary interface, and all
> partitions, emit an idempotent initialization function that (a) calls
> the init fn of all imports and then (b) performs all dynamic inits of
> namespace scope.
>
> In a non-module world a function that performs #b would then arrange to
> be called at startup via .init or similar. In a module-world, we do not
> (need to) do this, as we know it'll be called somewhere by an import.
>
> However, Q1 raises the possibility that an implementation partition may
> not be imported anywhere, so its global initializer fn is never called
> from another global init. We therefore have to arrange for it to be
> called from .init as a regular initializer function. A small pessimization.
>
> Q2 raises the same question wrt primary interfaces. If they might never
> be imported, again, their initializer fn would never be called by that
> mechanism. We have to emit it via .init.
>
> nathan
>


--
Nathan Sidwell

Received on 2022-06-09 19:55:34