Casting away immutability

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Sep 1 19:50:18 PDT 2015


On Wednesday, September 02, 2015 02:04:58 Sergei Degtiarev via Digitalmars-d-learn wrote:
> I can't understand how cast coexist with immutability. Consider
> the code:
>   immutable immutable(int)[4] buf;
>   auto x=buf[0];
>   auto p=buf.ptr;
>
>   auto i=cast(int[]) buf;
>   i[]=1;
>
>   assert(buf.ptr == p);
>   assert(buf[0] != x);
>
> I've just modified immutable data, is it normal?
> Another, ever simpler, code:
>   immutable a=0;
>   auto b=cast(int*) &a;
>   *b=1;
>   assert(&a == b);
>   assert(a != *b);
> Last two assertions both succeed and really puzzle me. What is
> pointer in D at all?

You can cast away immutable, just like you can cast away const, but in
either case, mutating the data after casting it to mutable is undefined
behavior. The compiler is free to assume that you won't do that, and in the
case of immutable, if the data is actually in ROM, it could crash your
program.

The two main places that casting away const or immutable would be used at
this point would be to pass it to a C function which isn't properly
annotated (but which you know won't mutate the data) or when you cast to
immutable to pass something via std.concurrency and then to cast back to
mutable on the receiving thread, since we don't currently have a way to
indicate ownership in a manner that would allow us to pass mutable data
across threads. But if you do that, you need to be sure that you just passed
across the only reference to that data, or you're going to have bugs,
because anything which isn't immutable or shared is considered thread-local
by the compiler.

So, there are cases where it makes sense if you're very careful and know
what you're doing, but those cases are few and far between. But D allows the
cast if nothing else, because it's a systems language and will let you shoot
yourself in the foot if you really try to. And when you cast, you're telling
the compiler that you know better than it does. So, you'd better be right,
or you're going to blow your foot off (figuratively speaking).

Regardless, casting away const or immutable and then mutating is undefined
behavior. So, don't do it.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list