Adding empty static this() causes exception
Moritz Maxeiner via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Sep 12 13:39:28 PDT 2017
On Tuesday, 12 September 2017 at 19:59:52 UTC, Joseph wrote:
> On Tuesday, 12 September 2017 at 10:08:11 UTC, Moritz Maxeiner
> wrote:
>> On Tuesday, 12 September 2017 at 09:11:20 UTC, Joseph wrote:
>>> I have two nearly duplicate files I added a static this() to
>>> initialize some static members of an interface.
>>>
>>> On one file when I add an empty static this() it crashes
>>> while the other one does not.
>>>
>>> The exception that happens is
>>> Cyclic dependency between module A and B.
>>>
>>> Why does this occur on an empty static this? Is it being ran
>>> twice or something? Anyway to fix this?
>>
>> The compiler errors because the spec states [1]
>>
>>>> Each module is assumed to depend on any imported modules
>>>> being statically constructed first
>>
>> , which means two modules that import each other and both use
>> static construction have no valid static construction order.
>>
>> One reason, I think, why the spec states that is because in
>> theory it would not always be possible for the compiler to
>> decide the order, e.g. when executing them changes the
>> ("shared") execution environment's state:
>>
>> ---
>> module a;
>> import b;
>>
>> static this()
>> {
>> // Does something to the OS state
>> syscall_a();
>> }
>> ---
>>
>> ---
>> module b;
>> import a;
>>
>> static this()
>> {
>> // Also does something to the OS state
>> syscall_b();
>> }
>> ---
>>
>> The "fix" as I see it would be to either not use static
>> construction in modules that import each other, or propose a
>> set of rules for the spec that define a always solvable subset
>> for the compiler.
>>
>> [1] https://dlang.org/spec/module.html#order_of_static_ctor
>
> The compiler shouldn't arbitrarily force one to make arbitrary
> decisions that waste time and money.
My apologies, I confused compiler and runtime when writing that
reply (the detection algorithm resulting in your crash is built
into druntime).
The runtime, however, is compliant with the spec on this AFAICT.
> The compiler should only run the static this's once per module
> load anyways, right?
Static module constructors are run once per module per thread [1]
(if you want once per module you need shared static module
constructors).
> If it is such a problem then some way around it should be
> included: @force static this() { } ?
The only current workaround is what Biotronic mentioned: You can
customize the druntime cycle detection via the --DRT-oncycle
command line option [2].
> The compiler shouldn't make assumptions about the code I write
> and always choose the worse case, it becomes an unfriendly
> relationship at that point.
If your point remains when replacing 'compiler' with 'runtime':
It makes no assumptions in the case you described, it enforces
the language specification.
[1] https://dlang.org/spec/module.html#staticorder
[2] https://dlang.org/spec/module.html#override_cycle_abort
More information about the Digitalmars-d-learn
mailing list