On Thu, Oct 18, 2018 at 6:50 AM Steven Schveighoffer via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > > On 10/18/18 9:35 AM, Steven Schveighoffer wrote: > > > > struct NotThreadsafe > > { > > private int x; > > void local() > > { > > ++x; // <- invalidates the method below, you violate the other > > function's `shared` promise > > } > > void notThreadsafe() shared > > { > > atomicIncrement(&x); > > } > > } > > > > [snip] > > > But on top of that, if I can't implicitly cast mutable to shared, then > > this ACTUALLY IS thread safe, as long as all the casting in the module > > is sound (easy to search and verify), and hopefully all the casting is > > encapsulated in primitives like you have written. Because someone on the > > outside would have to cast a mutable item into a shared item, and this > > puts the responsibility on them to make sure it works. > > > > Another thing to point out -- I can make x public (not private), and > it's STILL THREAD SAFE.
I'm not sure that's an interesting design goal though. Most things don't have shared methods. If you're writing a thing with shared methods, you're very in the business of implementing threadsafety... you're going to want to make it the tightest, most-unlikely-to-have-threading-bugs thing you can write. I predict that you're not going to be upset about the restriction. And if you are, AND you're confident in your application to maintain a mutually-exclusive shared/TL separation, then you can do this to your hearts content! Nobody will stop you, and it will be fine. But I don't think it should be default, because the rules as designed that way, enforce *users* to perform unsafe casts when they're, on average, not qualified to make those decisions.