valid uses of shared

Steven Schveighoffer schveiguy at yahoo.com
Fri Jun 8 10:13:27 PDT 2012


On Fri, 08 Jun 2012 10:57:15 -0400, Artur Skawina <art.08.09 at gmail.com>  
wrote:

> On 06/08/12 06:03, Steven Schveighoffer wrote:

>>
>> I agree that the type should be shared(int), but the type should not  
>> transfer to function calls or auto, it should be sticky to the  
>> particular variable.  Only references should be sticky typed.
>
> The problem with this is that it should be symmetrical, IOW the  
> conversion
> from non-shared to shared would also have to be (implicitly) allowed.
> A type that converts to both would be better, even if harder to  
> implement.

It should be allowed (and is today).  I am talking about stripping  
head-shared, so shared(int *) automatically converts to shared(int)* when  
used as an rvalue.

>> Right, I was thinking shared structs do not make sense, since I don't  
>> think shared members do not make sense.  Either a whole struct/class is  
>> shared or it is not.  Because you can only put classes on the heap,  
>> shared makes sense as an attribute for a class.
>>
>> But then again, it might make sense to say "this struct is only ever  
>> shared, so it should be required to go on the heap".  I like your idea  
>> later about identifying shared struct types that should use  
>> synchronization.
>
> Of course shared structs make sense, it's what allows implementing any
> non-trivial shared type.
>
>    static Atomic!int counter;
>
> inside a function is perfectly fine. And, as somebody already mentioned
> in this thread, omitting 'static' should cause a build failure; right
> now it is accepted, even when written as
>
>    shared Atomic!int counter;
>
> The problem? 'shared' is silently dropped. Move the counter from a struct
> into a function after realizing it's only accessed from one place, forget
> to add 'static' - and the result will compile w/o even a warning.

The difference is that static is not a type constructor.

e.g.:

shared int x; // typeof(x) == int

void foo(shared int *n){...}

foo(&x); // compiler error?  huh?

I think this is a no-go.  Shared has to be statically disallowed for local  
variables.


>> Yes, head stripping.  I think it should be allowed.  For instance, if  
>> you wanted to read a shared double, and take the cosine of it, this  
>> should be allowed:
>>
>> auto n = cos(sharedValue);
>>
>> If it's not, the alternatives are:
>>
>> auto n = cos(cast()sharedValue);
>>
>> or
>>
>> double v = sharedValue; // explicit removal of shared
>> auto m = cos(v);
>>
>> Neither of these look necessary, I think just allowing shared value  
>> types to automatically convert to non-shared versions works the best.
>
> If 'shared(VT)' implicitly converts to VT, then
>
>    auto myY = x.y; // typeof(myY) == shared(int)
>
> would still be fine.

No, because then &myY yields a reference to shared data on the stack,  
which is what I think should be disallowed.

My recommendation is that typeof(myY) == int.

> But I'm not sure allowing these implicit conversions is a good idea.
> At least not yet. :)

Implicit conversions to and from shared already are valid.  i.e. int x =  
sharedInt; is valid code.  I'm talking about changing the types of  
expressions, such that the expression type is always the tail-shared  
version.  In fact, simply using a shared piece of data as an rvalue will  
convert it into a tail-shared version.

-Steve


More information about the Digitalmars-d mailing list