On 08/17/2011 11:09 PM, Jonathan M Davis wrote:
On Wednesday, August 17, 2011 13:31 Martin Nowak wrote:
Not wanting to drift too far off topic I'll add one last point.
given:
immutable(int[]) data = assumeUnique(myints);
send(cast(int[])data);
writeln(data[0]);

A compiler implementation could deduce data won't change between
initialization and the write.
Thus performing optimizations that would break the code.
I think that and being able to store ctfe data in read only sections are
the reasons for the undefined behavior.
Removing Immutable With A Cast =>
http://www.digitalmars.com/d/2.0/const3.html

Yes, because you actually kept the data on the original thread. The _only_ way
that passing via send by casting to and from share or to and from immutable is
going to work properly if you _do not keep the data on the original thread_.
By casting to either shared or immutable, you're breaking the guarantees that
the compiler makes and expects. So, doing something like using that data again
on the original thread is broken regardless. The _only_ time that this way of
passing mutable data via send is okay is when you're actually passing full
ownership of the data across and never touching it on the original thread
again (unless you pass it back across the same way, handing over ownership
again). Your code is broken regardless of whether you're using immutable or
shared. True, immutable might be more thoroughly optimized than shared is
therefore more likely to break, but the code is broken regardless.

- Jonathan M Davis

No, casting shared and back carefully does not break the code, as I pointed out in my previous post. Casting immutable and back does.

You don't break the guarantees the compiler expects and makes with transferring ownership by cast to shared and back.


int         // this variable is visible to one thread only
shared(int) // this variable might be visible to multiple threads


If you *know* that your shared variable is visible by only one thread, you can safely cast it to unshared, without breaking any guarantees.

You can always safely cast to shared, because shared gives less guarantees.

Doing it by casting to immutable and back, on the other hand, is wrong.

int            // this variable may change its value
immutable(int) // this variable may not

If you *know* that your mutable variable is never going to change, you can safely cast it to immutable, without breaking any guarantees.

If you *know* that your immutable variable is never going to change after the cast, you can safely cast it to mutable, without breaking any guarantees.

But in this case it is probably going to change, so it does not work with immutable. shared and immutable are two very different things.





Reply via email to