Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Templated static ctor + separate compilation = module cycles #17706

Open
dlangBugzillaToGithub opened this issue Apr 28, 2015 · 6 comments
Open

Comments

@dlangBugzillaToGithub
Copy link

Steven Schveighoffer (@schveiguy) reported this on 2015-04-28T19:41:54Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=14517

CC List

Description

Even though druntime plays a role, I'm marking this as DMD, since druntime cannot figure this out without compiler help.

Example:

mod1.d ==========

module mod1;
import std.stdio;

struct S(T)
{
   shared static T t;
   shared static this() {writeln(T.stringof); _t = 5;}
}

void main() {}

mod2.d ==========

module mod2;

import mod1;
import mod3;

S!int x;

mod3.d ==========

module mod3;

import mod1;
import mod2;

S!int x;

command line ====

dmd mod1.d mod2.d mod3.d
./mod1
int
dmd -c mod2.d
dmd -c mod3.d
dmd mod1.d mod2.o mod3.o
./mod1

object.Exception@src/rt/minfo.d(162): Aborting: Cycle detected between modules with ctors/dtors:
mod2 -> mod3 -> mod2

================

Note that the module ctor only runs once (I only see one printout of 'int'), so at least that is figured out at runtime.

Examination of the module info using druntime debugging printfs shows that in the first case (when all 3 modules are compiled at once), mod1 is marked as having a static CTOR, mod2 and 3 are not. In the second case, mod1 is not marked as having a static ctor, mod2 and mod3 are.

I wonder if a separate "linkage" module info with just the static ctors dependent on both modules should be created with a dependency on the instantiating and the template module could be created, which should eliminate any issues (it's definitely possible right now to construct a cycle between instantiating and template modules). The instantiating module should have a dependency on the linkage module as well, since there could be a cycle there also! It's a very complex issue, but probably not very common.
@dlangBugzillaToGithub
Copy link
Author

issues.dlang (@jmdavis) commented on 2015-04-28T20:05:44Z

This currently blocks https://github.com/D-Programming-Language/druntime/pull/990 from working.

@dlangBugzillaToGithub
Copy link
Author

schveiguy (@schveiguy) commented on 2015-04-28T20:20:46Z

It's not a blocker, as we can work around that, see my new comments in the PR.

@dlangBugzillaToGithub
Copy link
Author

code (@MartinNowak) commented on 2015-04-28T21:36:18Z

You probably learned that for C++, avoid static constructors because the initialization order quickly becomes a mess.
The problem here is that both mod2 and mod3 depend on a constructor, but also have a cyclic dependency. We could somehow (using linker tricks) try to push the ctors/dtors into mod1.
I'm not sure I understand your idea Steven.

@dlangBugzillaToGithub
Copy link
Author

schveiguy (@schveiguy) commented on 2015-04-28T22:16:16Z

If you look at PR 990 that Jonathan linked, you will see that it's not so cut and dry. Essentially ANY separate compiled module that imports another module that has some template constructors, even if they aren't used in that module, but used somewhere else, will flag that module as having ctors.

The test I ran showed modules like std.traits having module bits flipped on because of core.time having static ctors in an instantiated template. That makes no sense whatsoever -- there's not even an instantiation of MonoTimeImpl in std.traits.

Let me first say that we need to fix this regardless of how it's done or how complete the fix is. We absolutely cannot mark some module as having static ctors because of modules somewhere else in the import chain that have nothing to do with the given module. If this means banning static ctor/dtor in templates, so be it (though I think that's a bit difficult to swallow).

And thinking some more about my idea, I don't think it will work. What we likely need is a way to say that mod2 or mod3 can "upgrade" mod1's bit (at runtime). Perhaps we can discuss at dconf '15.

@dlangBugzillaToGithub
Copy link
Author

bugzilla (@WalterBright) commented on 2015-07-02T22:05:43Z

some help: https://github.com/D-Programming-Language/druntime/pull/1314

@dlangBugzillaToGithub
Copy link
Author

pro.mathias.lang (@Geod24) commented on 2020-08-06T11:08:15Z

This might be related to https://issues.dlang.org/show_bug.cgi?id=20641 which triggers with separate compilation + module ctors in templated code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant