On Thursday, 14 June 2012 at 11:11:57 UTC, Jonathan M Davis wrote:
I haven't had the chance to look over your code yet, but this
looks
_seriously_ suspect. Casting to and from immutable or cast away
const are
things that should be done _very_ rarely. One of the few times
that casting to
immutable makes any sense is when you need an object to be
mutable while you
put it together and then immutable afterwards. But when you do
that, that
reference or pointer is the _only_ reference to that data. e.g.
auto func(size_t numElems)
{
auto arr = new int[](numElems);
foreach(ref e; arr)
//do something to initialize e
return cast(immutable int[])arr;
}
Taking a function's parameter (which came from who-knows-where)
and casting it
to immutable is almost certainly a terrible thing to do. If
there are _any_
other references to that data, you will have bugs. immutable is
supposed to
guarantee that the data is _never_ altered. So, when you cast
something to
immutable, you're telling the compiler that it's okay to treat
that data as
immutable and that you will _not_ have any mutable references
to that data or
alter it in any way. If you do, you'll be breaking the
compiler's guarantees.
Ideally, you would always construct immutable objects as
immutable rather than
creating them as mutable and then casting them to immutable,
but that's not
always possible.
And taking your payload, which is immutable, and casting away
immutable when
you return it from front is truly bad. Casting away const or
immutable and
then mutating that object is _undefined_ behavior. Do _not_ do
it unless you
have to and know what you're doing.
These stackoverflow questions may help you understand better:
http://stackoverflow.com/questions/4219600/logical-const-in-d
http://stackoverflow.com/questions/10364837/why-do-i-have-to-cast-this
- Jonathan M Davis
OK, clear. Thanks!
I was thinking that casting is bad here, but wanted to give the
user ability to pass any object inside constructor. Now I see
that this is a bad idea given transitivity of immutable.
In .NET readonly applies only to fields inside objects preventing
assignments to them from other places than constructors. But I
can assign another instance of an object with readonly fields to
the same variable. Then I can pass that instance to some
constructor and assign it to a readonly field.
How to achieve the same in D? As far as I understand, it is not
possible for structs with immutable fields, and it is not clear
for me about classes.
In other words:
Does a variable always point to the same place in memory and
assigning to it simply copies data to that place? I don't
understand whether it is possible to make it point to another
place. That would be a mutable variable pointing to a type with
immutable fields. After that I want to assign an instance of that
type to an immutable field in constructor. Can I do so, or that
would be bad?