On Friday, 24 July 2015 at 20:08:11 UTC, Steven Schveighoffer
wrote:
On 7/24/15 3:35 PM, Jonathan M Davis wrote:
Your case works, because the const reference is gone after the
cast, and
there are no others that were created from the point that it
temporarily
became const. So, it's a very special case. And maybe the rule
can be
worded in a way that incorporates that nicely, whereas simply
saying
that it's undefined behavior to cast away const and mutate
would not
allow it. But we cannot say that it's defined behavior to cast
away
const and mutate simply because you know that the data is
mutable, or we
do not have physical const, and const provides no real
guarantees.
I agree, we can't just make the general case that you can cast
away const if you know the data is mutable, given some
configuration of function calls. There has to be complete
visibility to the compiler within the same function to allow
the possibility that some mutable data changed.
We can start with "casting away const and mutating, even if you
know the underlying data is mutable, is UB, except for these
situations:..."
The only except that makes any sense to me is when you're casting
away const from the last const reference, so there are no const
references left for the compiler to make any assumptions - so the
case where you're trying to mimic inout. Something like
----
int x;
const int *y = &x;
*(cast(int *)y) = 5;
----
should be completely invalid IMHO. I don't see any reason to make
it valid to cast away const and mutate just because the compiler
can see that that's what you're doing, especially when it doesn't
buy you anything, since you have access to the mutable reference
anyway. Allowing it would just complicate things.
It might be possible to word the spec in a way to essentially
allow you to do your own inout when inout doesn't cut it, since
you're not really violating what const is supposed to guarantee,
but for the rest, I say leave it undefined, because in that case
you are violating it.
- Jonathan M Davis