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