common types + type modifiers

Ellery Newcomer ellery-newcomer at
Sun Jan 30 10:23:16 PST 2011

On 01/30/2011 09:47 AM, Michel Fortin wrote:
> On 2011-01-29 20:09:11 -0500, Ellery Newcomer
> <ellery-newcomer at> said:
>> trying to wrap my head around shared,const,immutable (not inout yet,
>> though someday I'll need to figure out what it's supposed to do)
>> Currently, dmd doesn't exhibit a lot of consistency wrt the above, so
>> bear with me as I question every ____ing thing it does.
>> my [erroneous?] understanding of the modifiers:
>> shared - many threads can see
>> lack of shared - one thread can see plus some difference or other in
>> physical layout (of which I am mostly ignorant)
>> immutable - nobody can mutate
>> lack of immutable - anybody can mutate
>> const - either immutable or mutable - you can't mutate because you
>> don't know which, but you also can't rely on it not mutating
>> shared(immutable(T)) == immutable(T) because who care who can see it
>> if nobody can mutate it
>> otherwise, shared(T) != T where T is not shared or immutable because T
>> might be mutable and then it matters who can see it and when
>> What is the common type of two types with the same base T but
>> different modifiers?
>> My [erroneous?] [generic] reasoning:
>> (notation - i under T1 means T1 == immutable(T), etc)
>> T1 : T2 -> ResultT
>> i c c follows from my defs above
>> i m c ditto
>> c m c ditto
>> I think this is what dmd does. seems obvious.
> Everything is correct up to here.
>> what about shared?
>> shared(U) : U -> ?? where U is not shared or immutable
>> the result is some sort of a 'maybe shared' - it definitely can't be
>> U. Can it be shared(U) ? I'm not sure about the semantics of tls, but
>> it seems like that would violate U's contract that only one thread can
>> see [and mutate] it. So it seems to me that there is no common type of
>> shared(U) and U.
> Indeed, U and shared(U) have no common type.
>> unless it's acceptable to just make the mutability const. which would
>> give:
>> cs m cs
>> cs c cs
>> ms m cs
>> ms c cs
> No, that doesn't work. There is no common type between shared and
> non-shared.
>> otherwise, its a shared/shared or immutable/shared pair, so the result
>> type is shared, and the mutability is the same as for
>> unshared/unshared. which, come to think of it, will always be const.
>> So the result type will be const shared(T)
>> So that's my generic reasoning, which doesn't take the semantics of
>> subtypes, ease of use, etc, into account. here are some cases which I
>> suspect are wrong:
>> const(int) : int -> int
>> const(int) : shared(int) -> int
>> and
>> shared(const(int*)) : const(int*) -> const(int)*
>> 1) why can we do away with the constness of the pointer?
>> 2) I think we should not do away with the sharedness of the pointer,
>> let alone of the element (shared is transitive too, isn't it? it has
>> to be..)
> About the constness of the pointer, you should only be able to do this
> when you make a copy of the pointer, as in:
> const(int*) a;
> const(int)* b = a;
> There is no const violation here because pointer 'b' is a new variable,
> distinct of 'a'. The data it points to however is the same, so the 'int'
> must stay const.
> That said, shared(const(int*)) and const(int*) do not have a common type
> since one is shared and the other is not.

Ah, thank you. That clears things up a bit. how do you safely convert 
from a shared type to a non shared type or vice versa? a deep copy 
inside a critical section?

More information about the Digitalmars-d-learn mailing list