casting away const and then mutating

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 23 16:57:53 PDT 2015


On Thursday, 23 July 2015 at 18:43:03 UTC, anonymous wrote:
> On a GitHub pull request, Steven Schveighoffer (schveiguy), 
> Jonathan M Davis (jmdavis), and I (aG0aep6G) have been 
> discussing if or when it's ok to cast away const and then 
> mutate the data:
>
> https://github.com/D-Programming-Language/phobos/pull/3501#issuecomment-124169544
>
> I've been under the impression that it's never allowed, i.e. 
> it's always undefined behaviour. I think Jonathan is of the 
> same opinion.

It's come up time and time again with discussions for logical 
const. If you cast away const, it's up to you to guarantee that 
the data being referenced is not mutated, and if it is mutated, 
it's undefined behavior.

Now, if you know that the data being referenced is actually 
mutable and not immutable, and you know that the compiler isn't 
going to make any assumptions based on const which are then wrong 
if you mutate the variable after casting away const, then you can 
get away with it. But it's still undefined behavior, and if the 
compiler later starts doing more than it does now based on the 
knowledge that you can't mutate via a const reference, then your 
code might stop working correctly. So, if you're _really_ 
careful, you can get away with casting away const and mutating a 
variable, but you are depending on undefined behavior.

> Steven disagrees and thinks that there are cases where it's ok. 
> Namely, this simple case would be ok:
>
> ----
> int x;
> const int *y = &x;
> *(cast(int *)y) = 5;
> ----
>
> As I understand him, he's arguing that since the data is 
> mutable, and since no function boundaries are crossed, 
> compilers should not be allowed to do anything but the obvious 
> with that code.

Even if this were defined behavior, what would be the point? You 
have access to x. You could just mutate it directly. I don't see 
how it would make any sense to be attempting to mutate something 
via a const reference when you have access to it via a mutable 
reference. It's when you don't have access to it via a mutable 
reference that it becomes an issue - which means that you've 
crossed a function boundary.

As far as I can tell, making the above defined behavior buys you 
nothing. The times when you gain something from being able to 
cast away const and mutate are the times when you've crossed 
function boundaries and you have to assume that the calling code 
can't see that the cast is happening and thus can't see that the 
data it passed it might have been mutated even though it was 
const. The times where being able to cast away const and mutate 
would be valuable are exactly the times when that would be 
violating the purpose of const - that the data isn't changed via 
a const reference.

The only way to make casting away const and mutating defined 
behavior in general is to make it so that the compiler can't make 
assumptions based on const, which does tend to defeat the purpose 
of const on some level. And part of the whole deal with D's const 
is that it's actually physical const and not logical const or 
C++'s const or any other type of const, and if that's the case, 
then casting away const and mutating is _not_ something that 
should be defined behavior. If it were, then we wouldn't be 
dealing with physical const anymore. Instead we'd be in the same 
boat as C++ where const didn't actually mean that the object 
wasn't mutated, since you could cast away mutate - just with the 
caveat that you have to be sure that the data wasn't actually 
immutable, since mutating immutable data _definitely_ breaks 
immutable, and it could segfault, depending on where the data is 
stored.

So, I don't see how we say that it makes sense for const to ever 
be cast away and then mutated. That violates the guarantees that 
const is supposed to provide and puts us back in the C++ boat, 
only worse, since you still have to worry about immutable and not 
mutating const when it's actually immutable.

- Jonathan M Davis


More information about the Digitalmars-d mailing list