On Monday, 1 October 2018 at 06:06:31 UTC, ag0aep6g wrote:
`shared` isn't analogous to `const`. It's analogous to `immutable`. Functions dealing with `shared` data can assume that other threads also see the data as `shared`. If you allow calling `shared` methods on non-`shared` objects, you're breaking that.

Example:

----
struct Bob
{
  int* p;
  void doThing() shared
  {
    p = &s;
  }
}

shared int s;

void main()
{
  Bob bob;
(cast(shared Bob)bob).doThing();/* You'd make the cast implicit. */

  import core.thread;
  import core.atomic;
  enum n = 1_000_000;
auto t = new Thread(() { foreach (i; 0 .. n) atomicOp!"+="(s, 1); });
  t.start();
  foreach (i; 0 .. n) ++*bob.p;
  thread_joinAll();

  import std.stdio;
  writeln(s); /* usually not "2000000", because of race */
}
----

We've realised that.

In order to be safe, a mutable parameter can be implicitly cast to shared iff the parameter is also scope (that includes the `this` reference`). With an implicit cast in place of the explicit cast under the new rules it would fail to compile because the `this` reference is not scope.

Reply via email to