implicit conversions to/from shared

ag0aep6g via Digitalmars-d digitalmars-d at puremagic.com
Sun Jul 10 06:02:17 PDT 2016


While messing with atomicLoad [1], I noticed that dmd lets me implicitly 
convert values to/from shared without restrictions. It's in the spec 
[2]. This seems bad to me.

Here's how I understand shared. If anything's wrong, I'd appreciate if 
someone would educate me.

Shared is there to prevent me from accidentally writing code that's not 
thread-safe (at a low level).

When I never use shared (or __gshared or other mean hacks), I only ever 
get thread-local variables and I can't share data between threads. I get 
thread safety by avoiding the issue entirely.

When I do use shared, the compiler is supposed to reject (low-level) 
operations that are not thread-safe. That's why ++x is deprecated for a 
shared x, and I'm told to use atomicOp!"+=" instead.

Of course I can still do a verbose unsafe version which the compiler 
can't catch:

     atomicStore(x, atomicLoad(x) + 1);

The compiler can't possibly know which high-level operations need to run 
uninterrupted, so there's nothing it can do about this.

Back to implicit conversions. Loading and storing is as low-level as it 
gets. When D disallows unsafe ++ on shared, surely it should also 
disallow unsafe loading and storing.

Copying a shared value type to an unshared one could be defined as doing 
an atomic load, and copying the other way around could result in an 
atomic store. I don't think it's specified or implemented like this at 
the moment, but it would make sense to me. Loading/storing overly large 
value types can probably not be made thread-safe like that.

So, conclusion/proposal:

* Conversion of a value type from shared to unshared should only be 
allowed if it can be done with an atomic load. The compiler should 
generate the atomic load.
* Conversion of a value type from unshared to shared should only be 
allowed if it can be done with an atomic store. The compiler should 
generate the atomic store.
* Other conversions are not allowed.

Or alternatively, simply disallow all those conversions, and tell the 
user that they have to ensure thread safety themselves, e.g. by using 
atomicLoad/atomicStore.

Sorry for the noise if this is all known and part of the "shared isn't 
implemented" mantra. I couldn't find a bugzilla issue.


[1] https://github.com/dlang/druntime/pull/1605
[2] https://dlang.org/spec/const3.html#implicit_conversions (first sentence)


More information about the Digitalmars-d mailing list