November 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

--- Comment #8 from Walter Bright <bugzilla@digitalmars.com> ---
A module generates a ModuleInfo if at least one of these is true:

1. it imports a module that generates ModuleInfo
2. it has a static constructor
3. it has a static destructor
4. it has a unit test declaration

but is disabled if -betterC is on. This particular bug report is the result of having a static constructor.

--
November 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

--- Comment #9 from Walter Bright <bugzilla@digitalmars.com> ---
Iain has the right idea. The solution is to, when in -betterC mode:

1. automatically annotate static constructors with:

    pragma(crt_constructor) extern (C)

2. do the same for static destructors

3. not set `needmoduleinfo` for (1) and (2)

This will run the constructors and destructors using the C runtime library mechanism. The downside of this is the order of construction and destruction will be in the order the object files are seen by the linker, rather than a depth-first hierarchical order.

----

Mathias' suggestion is a good one. Give an error on `static this()`, and only
work with `shared static this()`.

--
November 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |blocker

--
November 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

--- Comment #10 from Walter Bright <bugzilla@digitalmars.com> ---
That doesn't quite solve the problem. Will have to think about it some more.

--
November 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

--- Comment #11 from Walter Bright <bugzilla@digitalmars.com> ---
mylib1.d has a static constructor in it. When does construction happen?

In C code, the C runtime takes care of it, in the order they appear to the linker.

In D code, the D startup code takes care of it, *after* the C runtime does its initializations, in depth-first order.

The two are different, and are irreconcilable (though most static constructors probably don't care about the order, we can't really rely on that).

myexe.d has no way to know that it is importing a betterC module, so it can't do the right thing with the construction.

So, I propose another solution. mylib1.d simply has to choose whether it wants to do C construction or D construction. C construction would be:

    pragma(crt_constructor) extern (C) static this() { ... }

D construction would be:

    static this() { ... }

myexe.d, upon seeing the D static constructor, is going to expect a ModuleInfo from mylib1.d. The compiler, when compiling mylib1.d with -betterC, and it sees a D static constructor, can create a ModuleInfo for that static constructor.

The programmer creating a betterC library for both betterC and D programs, would use:

    pragma(crt_constructor) extern (C) static this() { ... }

--
November 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

--- Comment #12 from Richard Cattermole <alphaglosined@gmail.com> ---
D module constructors of course shouldn't work in -betterC code. They can throw a warning as dead code and hence don't require ModuleInfo to be generated (this should be easy to resolve). That'll prevent surprises in the future.

However, the fundamental problem here is with pay-as-you-go runtime. You can't turn on ModuleInfo when you need it in -betterC to move you into pay-as-you-go area of the scale.

We can't turn on ModuleInfo generation right now, because DllImport is incomplete (a good bit harder to implement). If we did turn it on right now, it would result in segfaults if you have D DLL's with D with the runtime executable.

I am arguing that instead of fixing this bug, we solve the DllImport issues first and use code like this as test cases to verify that it is indeed fixed.

--
December 01, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

--- Comment #13 from Walter Bright <bugzilla@digitalmars.com> ---
In this case, ModuleInfo is how the D runtime runs static constructors. Programs compiled with betterC are meant to link only with the C runtime library, which knows nothing about ModuleInfo.

The problem here is writing a library that is compiled with betterC, and meant to be linked with either a betterC program or a D program.

Simply turning off ModuleInfo generation means the betterC's library does not run its static constructors.

Since a D program that is importing betterC modules does not know if they are betterC modules or not, it is the betterC modules' responsibility to choose how to do its own static construction.

I.e. a betterC module should use the following to run its static construction:

    pragma(crt_constructor) extern (C) void doMyStaticConstruction() { ... }

If a betterC is to be only linked with a D main, it should do:

    static this() { ... }

It should not do both, as then the static constructions will get run twice if it is linked with a D main.

The change to fix this bug report, then, is for betterC modules to generate a ModuleInfo if it has a `static this` constructor. And to add these instructions to the documentation.

The DLL export stuff is an orthogonal problem.

--
December 01, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

--- Comment #14 from Richard Cattermole <alphaglosined@gmail.com> ---
(In reply to Walter Bright from comment #13)
> The change to fix this bug report, then, is for betterC modules to generate a ModuleInfo if it has a `static this` constructor. And to add these instructions to the documentation.

This should not be automatic.

-betterC is a collection of switches all rolled in together. One of these is turning off of ModuleInfo generation. This is how it works in both LDC and GDC.

It needs to be opt-in via switches. Otherwise, behavior that wasn't expected may occur.

--
December 02, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|The __ModuleInfo member     |Modules compiled with
                   |spuriously linked for       |-betterC never generate a
                   |modules compiler with       |ModuleInfo
                   |-betterC                    |

--
December 02, 2022
https://issues.dlang.org/show_bug.cgi?id=22367

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #15 from Dlang Bot <dlang-bot@dlang.rocks> ---
@WalterBright created dlang/dmd pull request #14665 "fix Issue 22367 - Modules compiled with -betterC never generate a Mod…" fixing this issue:

- fix Issue 22367 - Modules compiled with -betterC never generate a ModuleInfo

https://github.com/dlang/dmd/pull/14665

--