Persistent list
Jonathan M Davis via Digitalmars-d
digitalmars-d at puremagic.com
Sun Nov 15 07:09:24 PST 2015
On Sunday, 15 November 2015 at 14:55:36 UTC, Dicebot wrote:
> On Sunday, 15 November 2015 at 14:42:25 UTC, Jonathan M Davis
> wrote:
>>> Casting away _const_ is already legal if programmer can
>>> himself guarantee underlying object has mutable origin (i.e.
>>> not available via immutable reference), by the very
>>> definition of const. It is casting away immutable and
>>> mutating that is strictly UB.
>>
>> No. As it stands, casting away const and mutating is _always_
>> considered undefined behavior, regardless of whether the
>> object being referred to is actually mutable, const, or
>> immutable. In fact, there was a discussion on that not long
>> ago, and the spec was updated to be clearer on that count -
>> with approval from Walter. AFAIK, it has never been the case
>> that casting away const and mutating was defined behavior in
>> D2 (I have no idea what the deal with D1 and const is other
>> than the fact that it was quite different).
>
> How was it justified to fit definition of `const`? It is in
> direct contradiction, because const is supposed to mean "can be
> either mutable or immutable, can't make any assumptions about
> it".
>
> My understanding from previous discussions was that mutating
> const is UB is general because mutating immutable is UB and
> const _may_ be a view to immutable data. And if this can be
> proved to not be the case, const is not really const anymore.
> In fact, major chunk of our ported code relies on this.
const in D guarantees that the object will not be mutated via
that reference regardless of what that reference refers to. And
there _are_ cases where the compiler can make assumptions based
purely on const, though they're not common. e.g.
auto bar(const Foo) pure;
auto foo = new Foo;
auto result = bar(foo);
After the call to bar, the compiler can guarantee that the value
of foo has not changed, because it's not possible for bar to
access foo except via a const reference, and it can clearly see
that, because it can see that it's not possible for bar to access
foo except via the reference that's passed to it. In fact, with
the following code
auto bar(const Foo) pure;
auto foo = new Foo;
auto result1 = bar(foo);
auto result2 = bar(foo);
it would be possible for the compiler to know that result1 and
result2 are identical and elide the function call like it could
if bar were given an immutable object. AFAIK, the compiler
doesn't do anything like that currently, but const is enough for
it to do so in this case. So, const my itself can provide
guarantees, even though usually the compiler doesn't have enough
information to do much with const alone (since it has to be able
to know that the object is not mutated via another, mutable
reference, which it usually can't).
Whenever this has come up, Walter has been adamant that D's const
is physical const and that it's guaranteed by the compiler that
you an object is not mutated via a const reference - regardless
of whether the object referred to is actually mutable, const, or
immutable.
Now, realistically, you're going to get away with casting away
const and mutating almost all of the time, because the
assumptions that the compiler can make on const alone are pretty
limited, but it's still undefined behavior.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list