On 2011-01-29 20:09:11 -0500, Ellery Newcomer
<ellery-newco...@utulsa.edu> 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.
--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/