Remaining const niggles #1 - Custom POD types

Christopher Wright dhasenan at gmail.com
Mon Feb 18 05:06:26 PST 2008


Janice Caron wrote:
> On 18/02/2008, Christopher Wright <dhasenan at gmail.com> wrote:
>>> One cannot "unconst" something without an explicit cast. This is
>>> precisely what I aim to avoid. The explicit cast should be
>>> unnecessary, whether within opImplicitCast (or any other function), or
>>> not.
>> Yes you can:
>>
>> struct Something {
>>     int member; //...
>>     Something opImplicitCast() const {
>>        Something s;
>>        s.member = this.member;
>>        return member;
>>     }
>> }
> 
> Ah, but you're not thinking ahead. Right now, that may well work, but
> in the future, when the "struct const bug" is fixed, it will stop
> working. You're basically exploiting a bug there.

No, I'm forgetting the transitive nature of const.

> It's like this - if s is an instance of const(S), then, not only is s
> const, but /every member of s is also (transitively) const. Right now,
> the compiler doesn't know that, because it's a bug, but it will be
> fixed before too long. (It has to be, as it allows one to break
> constancy). Once that bug is fixed, you will no longer be able to do
> 
>     s.member = this.member;
> 
> because this.member will have type const(U), for some U, while
> s.member will have type U, and (...and this is the whole point of this
> thread...) const(U) will not implicitly cast to U. So sure, your
> example works today. But it most likely will not work tomorrow. The
> only way to guarantee that it will work post-bug-fix would be to write
> 
>     s.member = cast(something)(this.member);
> 
> instead.

True, unless your members all have a defined opImplicitCast to break 
const or are primitives. And unless they do, you don't know if it's safe 
to convert the containing type, so you shouldn't.

So my strategy works as long as you add the code to all your structs.

>> Whoever designed the struct can tell you whether it's safe to cast a
>> const form of it to a mutable form.
> 
> They can tell you their /intent/, but only the compiler can absolutely
> guarantee it. The compiler can /prove/ whether or not a given type is
> safe to copy.

True. There's value in that.

>> You need to tell the compiler whether it's okay to copy a const struct
>> into a mutable one.
> 
> First off, let me remind everyone that casting away const is undefined
> in D. Let me stress that point - /undefined/. That doesn't mean "use
> with caution", it means you should never, ever do it, except to call
> library functions which have been incorrectly declared.

opImplicitCast allows you to define a copy mechanism from a const UDT to 
a non-const UDT, as long as you can copy every member from a const one 
to a non-const one. This isn't casting away const; it's copying. You 
could call it dup() instead and have everything work, except for 
explicitly calling the method.



More information about the Digitalmars-d mailing list