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