digitalmars.D.learn - how to avoid "cycle detected"?
- aki (21/21) Jul 01 2015 Following code causes run-time error.
- ketmar (2/4) Jul 01 2015 you currently can't, sorry.=
- Jonathan M Davis via Digitalmars-d-learn (14/35) Jul 01 2015 Modules which have static constructors (or destructors) cannot import ea...
- Steven Schveighoffer (21/41) Jul 01 2015 You need to either factor out the static constructors to put them in a
- Jonathan M Davis via Digitalmars-d-learn (7/12) Jul 01 2015 I wouldn't mind that, but Walter shot that idea down previously when I w...
- aki (6/19) Jul 02 2015 Thanks for the discussion, now I understand there are
- Steven Schveighoffer (11/22) Jul 02 2015 With RTInfo for modules, we don't need any additional language support.
- Jonathan M Davis via Digitalmars-d-learn (18/40) Jul 03 2015 The last discussion that I had with Walter on supporting a way to tell t...
- Kapps (5/26) Jul 02 2015 An ugly solution, but the approach used in Phobos is to create
- aki (18/22) Jul 02 2015 How about this idea?
Following code causes run-time error. How can I use static this() without causing error? It's difficult to avoid this situation because actual code is more complex. file main.d: void main() { } file a.d: import b; class A { static this() {} }; file b.d: import a; class B { static this() {} }; object.Exception src\rt\minfo.d(162): Aborting: Cycle detected between modules w ith ctors/dtors: a -> b -> a
Jul 01 2015
On Wed, 01 Jul 2015 09:09:52 +0000, aki wrote:Following code causes run-time error. How can I use static this() without causing error?you currently can't, sorry.=
Jul 01 2015
On Wednesday, July 01, 2015 09:09:52 aki via Digitalmars-d-learn wrote:Following code causes run-time error. How can I use static this() without causing error? It's difficult to avoid this situation because actual code is more complex. file main.d: void main() { } file a.d: import b; class A { static this() {} }; file b.d: import a; class B { static this() {} }; object.Exception src\rt\minfo.d(162): Aborting: Cycle detected between modules w ith ctors/dtors: a -> b -> aModules which have static constructors (or destructors) cannot import each other, because the runtime has no way of knowing which order they should be run in or even if they _can_ be run in an order that guarantees that you don't use any variables before they're initialized. So, you either need to fix it so that your modules with static constructors aren't importing each (even indirectly), or you need to stop using static constructors in at least one of them. The result of this seems to often be that you should avoid static constructors where reasonably possible, but if your modules are independent enough, they should be fine. They _do_ need to be fairly independent of each other though, or you'll probably run into a problem with static constructors and cyclical imports eventually. - Jonathan M Davis
Jul 01 2015
On 7/1/15 5:09 AM, aki wrote:Following code causes run-time error. How can I use static this() without causing error? It's difficult to avoid this situation because actual code is more complex. file main.d: void main() { } file a.d: import b; class A { static this() {} }; file b.d: import a; class B { static this() {} }; object.Exception src\rt\minfo.d(162): Aborting: Cycle detected between modules with ctors/dtors: a -> b -> aYou need to either factor out the static constructors to put them in a leaf module, replace one of them with intializers, or remove one of them. It can be an exercise in ugly coding, but you can fix this. I know it wasn't specifically asked, but the reason it exists is simple: class A { static int x; static this() { x = B.x + 5;} } ... class B { static int x; static this() { x = A.x + 5;} } The runtime cannot introspect the code to detect the circular dependency, so it makes a conservative decision. I'm waiting on an introduction of RTInfo for modules [1] to allow us to mark static ctors as standalone, then we can probably fix this problem through a sort of "trust the programmer" mechanism. -Steve [1] https://issues.dlang.org/show_bug.cgi?id=10023
Jul 01 2015
On Wednesday, July 01, 2015 08:52:38 Steven Schveighoffer via Digitalmars-d-learn wrote:The runtime cannot introspect the code to detect the circular dependency, so it makes a conservative decision. I'm waiting on an introduction of RTInfo for modules [1] to allow us to mark static ctors as standalone, then we can probably fix this problem through a sort of "trust the programmer" mechanism.I wouldn't mind that, but Walter shot that idea down previously when I was arguing for adding a way to the language to tell the compiler that a static constructor didn't depend on anything else. He didn't want a "trust the programmer" mechanism in this case. I don't remember what his arguments were though. - Jonathan M Davis
Jul 01 2015
On Wednesday, 1 July 2015 at 22:25:48 UTC, Jonathan M Davis wrote:On Wednesday, July 01, 2015 08:52:38 Steven Schveighoffer via Digitalmars-d-learn wrote:Thanks for the discussion, now I understand there are technical difficulties. I have to give it a name like void staticInit(); and call it manually from main(). aki.The runtime cannot introspect the code to detect the circular dependency, so it makes a conservative decision. I'm waiting on an introduction of RTInfo for modules [1] to allow us to mark static ctors as standalone, then we can probably fix this problem through a sort of "trust the programmer" mechanism.I wouldn't mind that, but Walter shot that idea down previously when I was arguing for adding a way to the language to tell the compiler that a static constructor didn't depend on anything else. He didn't want a "trust the programmer" mechanism in this case. I don't remember what his arguments were though. - Jonathan M Davis
Jul 02 2015
On 7/1/15 6:25 PM, Jonathan M Davis via Digitalmars-d-learn wrote:On Wednesday, July 01, 2015 08:52:38 Steven Schveighoffer via Digitalmars-d-learn wrote:With RTInfo for modules, we don't need any additional language support. In Dconf '14, Walter said it was a good idea to add the RTInfo support for modules. I don't know if he voiced an opinion on the usage of it for flagging whether the static ctors are all standalone. But with support for modifying the runtime to reflect compile-time traits, we can at least play around with it. There are some things that are so obviously not dependent on anything (like initializing an AA), it's really quite annoying to have the runtime conservatively flag those as error. -SteveThe runtime cannot introspect the code to detect the circular dependency, so it makes a conservative decision. I'm waiting on an introduction of RTInfo for modules [1] to allow us to mark static ctors as standalone, then we can probably fix this problem through a sort of "trust the programmer" mechanism.I wouldn't mind that, but Walter shot that idea down previously when I was arguing for adding a way to the language to tell the compiler that a static constructor didn't depend on anything else. He didn't want a "trust the programmer" mechanism in this case. I don't remember what his arguments were though.
Jul 02 2015
On Thursday, July 02, 2015 06:56:26 Steven Schveighoffer via Digitalmars-d-learn wrote:On 7/1/15 6:25 PM, Jonathan M Davis via Digitalmars-d-learn wrote:The last discussion that I had with Walter on supporting a way to tell the compiler that a static constructor did not depend on another module was at least a couple of years ago I'd guess. So, he may have a different opinion on it now, and by using RTInfo, we wouldn't need his approval in quite the same way, so we may very well be able to do it now, but he was against the concept when we discussed it last (I don't think that the fact that we'd be adding language support vs runtime support was really an issue - it was the idea that we'd even have a way for the programmer to do what we're suggesting here by any mechanism). IIRC, part of the problem was the idea that it wouldn't be very hard for code to be marked as independent but inadvertently become depedent later and silent cause problems. In any case, I do tend to like the idea, since as it stands, we have to weed most static constructors out of Phobos, and it can be _very_ annoying, so I would not be averse to exploring the possibility, but just be aware that Walter has opposed it in the past, and it may take some doing to convince him (though maybe he's changed his opinion by now). - Jonathan M DavisOn Wednesday, July 01, 2015 08:52:38 Steven Schveighoffer via Digitalmars-d-learn wrote:With RTInfo for modules, we don't need any additional language support. In Dconf '14, Walter said it was a good idea to add the RTInfo support for modules. I don't know if he voiced an opinion on the usage of it for flagging whether the static ctors are all standalone. But with support for modifying the runtime to reflect compile-time traits, we can at least play around with it. There are some things that are so obviously not dependent on anything (like initializing an AA), it's really quite annoying to have the runtime conservatively flag those as error.The runtime cannot introspect the code to detect the circular dependency, so it makes a conservative decision. I'm waiting on an introduction of RTInfo for modules [1] to allow us to mark static ctors as standalone, then we can probably fix this problem through a sort of "trust the programmer" mechanism.I wouldn't mind that, but Walter shot that idea down previously when I was arguing for adding a way to the language to tell the compiler that a static constructor didn't depend on anything else. He didn't want a "trust the programmer" mechanism in this case. I don't remember what his arguments were though.
Jul 03 2015
On Wednesday, 1 July 2015 at 09:09:53 UTC, aki wrote:Following code causes run-time error. How can I use static this() without causing error? It's difficult to avoid this situation because actual code is more complex. file main.d: void main() { } file a.d: import b; class A { static this() {} }; file b.d: import a; class B { static this() {} }; object.Exception src\rt\minfo.d(162): Aborting: Cycle detected between modules w ith ctors/dtors: a -> b -> aAn ugly solution, but the approach used in Phobos is to create something like a_init.d which a.d imports, provided that the static ctors don't actually rely on things from the static ctor of b.
Jul 02 2015
On Thursday, 2 July 2015 at 17:21:03 UTC, Kapps wrote:An ugly solution, but the approach used in Phobos is to create something like a_init.d which a.d imports, provided that the static ctors don't actually rely on things from the static ctor of b.How about this idea? Allowing to define sub module in a module. file foo.d: module foo; // nameless module, automatically imported by outer module foo module { int[] needInitialize; static this() { needInitialize = ...; } } // use statically initialized variable needInitialize... Basically, d-lang's module has one-to-one correspondence with file. This new feature breaks this rule, but it's safe because this one is private to module foo. There are no way to import this nameless module by other modules. The purpose is just the alternative to making foo_init.d file. aki.
Jul 02 2015