On Thursday, 17 January 2013 at 08:46:22 UTC, Martin Drasar wrote:
Ok. But that leaves me with an unanswered question from one of
my
previous posts.
Casting away shared in undefined behavior. Although it may be not
written explicitly in dlang.org, once D will have a standard like
C or C++, it will be name like so.
In practice this means that behavior of program is uncertain and
may result in many consequences. In this case content of arrays
may be any of 1,2,3,4,5,6.
import std.concurrency : spawn;
import std.stdio : writeln;
shared int[] arr1;
shared int[] arr2;
static this()
{
arr1.length = arr2.length = 100;
foreach(ref e; arr1)
{
e = 1;
}
foreach(ref e; arr2)
{
e = 2;
}
}
void thread1()
{
int[] arr_1 = cast(int[])arr1;
int[] arr_2 = cast(int[])arr2;
arr_2[] = 3;
arr_1[] = 4;
}
void thread2()
{
int[] arr_1 = cast(int[])arr1;
int[] arr_2 = cast(int[])arr2;
arr_2[] = 5;
arr_1[] = 6;
}
void main()
{
spawn(&thread1);
spawn(&thread2);
writeln(arr1);
writeln(arr2);
}
Note, if you mark functions as @safe, the code will not compile,
because throwing shared is not allowed in D safe code.
What happens when you cast from and to shared? Is there any
moving in
memory from TLS and back? Or does it just access the memory as
if it
were in shared space?
It is implementation specific, but I guess nothing is moved, just
a variable is reinterpreted.
I have tried to compare addresses of b and _b, but writeln
refuses to
display an address of shared and assert does not help me
either. But
using the inspection capabilities of VisualD I found out that
they seem
to have the same address.
Thanks,
Martin
import core.stdc.stdio : printf;
import std.concurrency;
int a;
__gshared int b;
shared int c;
void thread()
{
printf("%p=%d\n%p=%d\n%p=%d\n", &a, a, &b, b, &c, c);
}
void main()
{
c = a = 2;
spawn(&thread);
printf("%p=%d\n%p=%d\n%p=%d\n", &a, a, &b, b, &c, c);
}
You can compile this code and look at addresses and assembly if
you are interested in implementation details.