Re: Adding empty static this() causes exception

2017-09-13 Thread Biotronic via Digitalmars-d-learn

On Tuesday, 12 September 2017 at 19:59:52 UTC, Joseph wrote:
The compiler shouldn't arbitrarily force one to make arbitrary 
decisions that waste time and money.


Like having a type system? Having to do *cast(int*)&s to 
interpret a string as an int isn't strictly necessary, and wastes 
dev time when they have to type extra letters.


Throwing an exception when there are import cycles that may cause 
problems is absolutely the correct thing to do. It's a choice 
between hard-to-figure-out errors that may depend on the order in 
which files were passed to the linker, and getting an exception 
before you've even started running your tests. If we could get 
this message at compile-time, that would of course be better, but 
that cannot be done in the general case due to separate 
compilation. If you want such a message in the cases where it is 
possible, feel free to create a pull request.


It would be possible to add a way to say 'ignore cycles for this 
module ctor', but as has been pointed out, cycles are generally a 
symptom of poor architecture, are brittle, and can almost always 
be avoided (and when they can't, there's a way around that too).


--
  Biotronic


Re: Adding empty static this() causes exception

2017-09-12 Thread lobo via Digitalmars-d-learn

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:

[...]


The compiler shouldn't arbitrarily force one to make arbitrary 
decisions that waste time and money.


My solution was to turn those static this's in to functions and 
simply call them at at the start of main(). Same effect yet 
doesn't crash. The compiler should only run the static this's 
once per module load anyways, right? If it is such a problem 
then some way around it should be included: @force static 
this() { } ? 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.


Solution is to redesign so there is no cycle because it is 
brittle and generally due to poor architecture. Like goto cyclic 
dependencies are occasionally useful, rarely necessary and avoid 
by default.


bye,
lobo


Re: Adding empty static this() causes exception

2017-09-12 Thread nkm1 via Digitalmars-d-learn

On Tuesday, 12 September 2017 at 19:59:52 UTC, Joseph wrote:
The compiler shouldn't arbitrarily force one to make arbitrary 
decisions that waste time and money.


You might want to educate yourself about arbitrary decisions that 
waste time and money: 
https://isocpp.org/wiki/faq/ctors#static-init-order




My solution was to turn those static this's in to functions and 
simply call them at at the start of main(). Same effect yet 
doesn't crash. The compiler should only run the static this's 
once per module load anyways, right? If it is such a problem 
then some way around it should be included: @force static 
this() { } ?


There is a way, turn static this's into functions and simply call 
them at the start of main().


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 you want C++, you know where to find it, although I wouldn't 
exactly call it "friendly".





Re: Adding empty static this() causes exception

2017-09-12 Thread Moritz Maxeiner via Digitalmars-d-learn

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


Re: Adding empty static this() causes exception

2017-09-12 Thread Joseph via Digitalmars-d-learn
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 solution was to turn those static this's in to functions and 
simply call them at at the start of main(). Same effect yet 
doesn't crash. The compiler should only run the static this's 
once per module load anyways, right? If it is such a problem then 
some way around it should be included: @force static this() { } ? 
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.


Re: Adding empty static this() causes exception

2017-09-12 Thread Biotronic via Digitalmars-d-learn

The simplest example of a cycle is probably this:

module A;
import B;

int n1 = 17;
static this() {
n1 = n2;
}

//
module B;
import A;

int n2 = 42;
static this() {
n2 = n1;
}

What's the value of n1 and n2 after module constructors are run? 
Since both module constructors can run arbitrary code, it's 
impossible to prove in the general case whether one of them 
depends on the other.


--
  Biotronic


Re: Adding empty static this() causes exception

2017-09-12 Thread Biotronic via Digitalmars-d-learn

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?


Seriously, simply adding static this() { } to module B crashes 
the program ;/ module A and module B both import each other 
because there are types that they need to share but that is 
all(one uses an enum of the other and vice versa).


https://dlang.org/spec/module.html#order_of_static_ctor

"Cycles (circular dependencies) in the import declarations are 
allowed as long as not both of the modules contain static 
constructors or static destructors. Violation of this rule will 
result in a runtime exception."


So if you have a static this() in both A and B, and A imports B 
and B imports A, you will get this error message. You can pass 
--DRT-oncycle=ignore to the program to hide the problem, but a 
better solution is to find a way to live with fewer static 
this()s.


The reason this exception is thrown is that one module's static 
this() might otherwise depend on another module's static this 
that depends on the first module again, and there is no good way 
to check if it actually depends or just potentially.


--
  Biotronic


Re: Adding empty static this() causes exception

2017-09-12 Thread Moritz Maxeiner via Digitalmars-d-learn

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




Adding empty static this() causes exception

2017-09-12 Thread Joseph via Digitalmars-d-learn
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?


Seriously, simply adding static this() { } to module B crashes 
the program ;/ module A and module B both import each other 
because there are types that they need to share but that is 
all(one uses an enum of the other and vice versa).