casting away const and then mutating
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Thu Jul 23 13:20:04 PDT 2015
On 7/23/15 2:43 PM, anonymous wrote:
> 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;
> ----
Yes, IMO, this should simply work and be consistent. The compiler could
use willful ignorance to assume x is still 0, but I find that to be
counterproductive. It would have to implement flow analysis to determine
that y must point at x, and then simply ignore the assignment during
that analysis.
I'll note that the reason I want to allow this, is because we have a
case where the same implementation must be used for the const and
mutable version of the function, but the return value is a template that
varies on constancy. Therefore, you necessarily need 2 function
definitions -- the compiler isn't smart enough (or maybe it's too
smart?) to use inout(T) as a template parameter to the Range struct, and
auto convert that back on return.
The nice thing about inout, is the compiler guarantees one
implementation of the function, and the implementation will guarantee
const is preserved. But on returning, the function puts the data back to
the way it was. That's exactly what we want.
In this case, we can't use inout. So we have to cast (or alternatively,
copy-paste implementation) one result to the other.
My opinion is, we should execute the implementation as if the object
were const, and then cast back to mutable if we are using the mutable
entry point. This allows the compiler to check the function
implementation for const-correctness, vs. the other suggestion: casting
the const object to a mutable one and then hoping the mutable function
implementation is const-correct without compiler help.
The proposed usage of casting also does not mutate the data in the
function that casts. It receives in a mutable object, and it outputs a
reference to the mutable object. The compiler would have to go through
great lengths to see that the source of the mutable range it's receiving
comes from a const range, and then ignore the type system in order to
elide a reloading of something that is miniscule compared to the
function call itself.
>
> 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.
>
> I think we've exchanged all arguments we have, yet no one has been
> convinced by the other side.
>
> We've found the language spec to be a bit sparse on this. All I could
> find is essentially "you can't mutate through a const reference" [1],
> but no mention of if/when it's ok to cast a const reference to a mutable
> one (and then mutate).
Note that it does specifically mention immutable cannot be cast away and
then modified (on that same page, see "Removing Immutable With A Cast").
It does not mention const, I assume that is on purpose.
-Steve
More information about the Digitalmars-d
mailing list