CURL review request

Jonathan M Davis jmdavisProg at gmx.com
Wed Aug 17 16:16:56 PDT 2011


On Wednesday, August 17, 2011 15:48 Timon Gehr wrote:
> 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.

Except that if you're dealing with a variable which was mutable, you cast it 
to immutable, and then you cast it back, you _know_ that it's actually 
mutable, and it will work just fine to mutate it.

With shared, you cast it to shared, pass it to another thread, and then you 
cast it back, you're also breaking the compiler's guarantees since the 
compiler is supposed to be able to guarantee that non-shared objects aren't 
accessible by multiple threads, but by having passed it to another thread, 
you're breaking those guarantees.

In both cases, it only works if when you pass the object to another thread, 
you don't use it again in the original thread. And in both cases, you're 
breaking the compiler's guarantees by doing what you're doing. I don't see why 
mutating an object which was mutable then immutable than mutable again is 
really any different from having an object be non-shared, shared, and then 
non-shared again on another thread, since in both cases you're circumventing 
the compiler and the only thing making it so that the compiler's guarantees 
hold is the fact that you actually passed ownership over to the new thread and 
haven't done anything with the object on the original thread after having 
passed it.

- Jonathan M Davis


More information about the Digitalmars-d mailing list