what exactly does cast(shared) and cast away shared do?

Johannes Loher johannes.loher at fg4f.de
Tue Jun 16 07:12:20 UTC 2020


Am 16.06.20 um 08:15 schrieb mw:
> I'm trying this program:
> 
> -----------------------------------------------------------------------------
> 
> class Foo {
>   int attr;
> 
>   this() {
>     writeln("Foo.ctor:", &attr);
>   }
> }
> 
> void threadInc(shared Foo foo) {
>   writeln("threadInc:", &foo);
>   writeln("threadInc:", &(foo.attr));
>   Foo f = cast(Foo)foo;
>   writeln("threadInc:", &f);
>   foo.attr = 123;
> }
> 
> void main() {
>   Foo foo = new Foo();
>   writeln("main:\t", &foo);
>   writeln("main:\t", &(foo.attr));
> 
>   spawn(&threadInc, cast(shared)foo);  // cannot pass foo: Error: static
> assert:  "Aliases to mutable thread-local data not allowed." Have to
> cast to shared
>   thread_joinAll();
> 
>   writeln("main:", foo.attr);
>   writeln("main:\t", &foo);
>   writeln("main:\t", &(foo.attr));
> 
>   shared sf1 = cast(shared)foo;
>   shared sf2 = cast(shared)foo;
>   writeln("sf1:\t", &sf1, "\t", &(sf1.attr));
>   writeln("sf2:\t", &sf2, "\t", &(sf2.attr));
> 
>   foo.attr = 456;
>   writeln("main:", foo.attr);
>   writeln("main:", sf1.attr);
>   writeln("main:", sf2.attr);
> }
> -----------------------------------------------------------------------------
> 
> 
> here is the result:
> 
> -----------------------------------------------------------------------------
> 
> Foo.ctor:7FB83F4B0010              <- &attr is always the same
> main:   7FFFD6D081F0               <- &foo
> main:   7FB83F4B0010
> threadInc:7FB83E1EFC08             <- cast(shared)foo
> threadInc:7FB83F4B0010
> threadInc:7FB83E1EFBF8             <- cast(Foo)foo, but != the original
> &foo
> main:123
> main:   7FFFD6D081F0               <- foo
> main:   7FB83F4B0010
> sf1:    7FFFD6D08200    7FB83F4B0010   <- each time cast(shared)foo will
> have a new addr
> sf2:    7FFFD6D08208    7FB83F4B0010   <- but &(x.attr) is always the same
> main:456
> main:456
> main:456
> -----------------------------------------------------------------------------
> 
> 
> In all the 3 cases, &(foo.attr) are the same; this is what I wanted,
> since the object is allocated on the heap.
> 
> But the memory address of the original foo, cast(shared) foo, and
> cast(Foo) foo are all different.
> 
> And for sf1, sf2, each time cast(shared)foo will have a new addr.
> 
> So every time cast(shared) / cast away shared will create a new wrapper
> to the original object, but all these wrappers' actual fields (the
> physical addr) stay the same?
> 
> What's the point of doing these wrappers every time?
> 
> Esp. for sf1, and sf2?  `shared` means it's globally *shared*,
> everywhere it's the same object, then why we have &(sf1) != &(sf2)?
> 
> 
> What's the exact semantics of cast(shared) and cast away shared?
> 
> 
> Thanks.
> 
This is because you are using different class variables and then take
their address. Of course the variables themselves have different
addresses on the stack, which is why you see different addresses. But as
you already noticed, they point to the same object. You get the exact
same behavior when using several regular variables (i.e. no shared
involved) that point to the same class object.

```
import std;

class A {}

void main()
{
    auto a = new A();
    auto b = a;
    writeln(&a); // 7FFF0D776E20
    writeln(&b); // 7FFF0D776E28
}
```

Classes are reference types, i.e. internally, they actually are
pointers. you can cast them to void* to see what they actually point to:

```
import std;

class A {}

void main()
{
    A a = new A();
    A b = a;
    shared(A) c = cast(shared A) a;
    A d = cast(A) c;
    writeln(&a); // 7FFF0D776E20
    writeln(&b); // 7FFF0D776E28
    writeln(&c); // 7FFE15993F80
    writeln(&d); // 7FFE15993F88
    writeln(cast(void*)a); // 7FD1AB5AA000
    writeln(cast(void*)b); // 7FD1AB5AA000
    writeln(cast(void*)c); // 7FD1AB5AA000
    writeln(cast(void*)d); // 7FD1AB5AA000
}
```

As you see, casting to shared and back inbetween doesn't have any effect
on the object the variables actually points to.


More information about the Digitalmars-d mailing list