The Status of Const

Steven Schveighoffer schveiguy at yahoo.com
Mon Aug 16 07:03:58 PDT 2010


On Mon, 16 Aug 2010 09:26:55 -0400, Michel Fortin  
<michel.fortin at michelf.com> wrote:

> On 2010-08-16 09:08:30 -0400, "Steven Schveighoffer"  
> <schveiguy at yahoo.com> said:
>
>> On Mon, 16 Aug 2010 08:56:51 -0400, Michel Fortin   
>> <michel.fortin at michelf.com> wrote:
>>
>>> The idea's not bad, but I think it needs some improvments. For  
>>> instance,  in a struct, I might want some members to be part of the  
>>> tail and some  other not. I believe that should be allowed somehow.
>>  What do you mean "not", meaning they are fully const?  Because you  
>> can't  not apply const to references inside a const struct, that's  
>> logical const,  and while it might be a nice feature, Walter has  
>> steadfastly refused to  allow it.
>
> I'm not arguing for logical const. Logical const means that you have an  
> island of non-const inside a const structure. That's not what I meant.
>
> When you want your struct to be tail-const, what it means is that you  
> want the members inside it to be tail-const. The structure itself is not  
> const, just the members, an just the tail of the members.
>
> But do you always want *all* the members to be tail const?

Yes.  Not doing this violates the promise of const.  This is exactly the  
same as logical const, even though the storage is not with the object  
itself.  It's ok to do it to the head members because the head part is  
always copied by value.

> Say your struct is a reference counting smart pointer that works by  
> having two pointers: one points to the actual object, the other points  
> to the reference counter (boost::shared_ptr's design). This smart  
> pointer basically has two tails, one for each internal pointer. But if  
> you apply "tail const" to the smart pointer, you probably only want the  
> pointer to the actual object to be tail-const. That's because making the  
> pointer to the reference counter tail-const would just prevent you from  
> updating the counter, which in turn would prevent you from assigning  
> something different to the smart pointer.

That's logical const.  I'm not saying it's not useful, but tail-const is  
not logical const.  A property of tail const that logical const does not  
share is that all referenced data in a const item is also constant in a  
tail-const reference.  The same is not true with logical const.

FWIW, I had proposed a complex system to Walter/Andrei that allowed for  
applying any kind of constancy to an object, and have the compiler deal  
with proper implicit casts.  However, the system is very complex, with  
people able to arbitrarily name const *flavors*.  It wouldn't have been  
very usable...

I think a possible solution is possibly to create a mutable library type  
that always stays mutable in const and immutable flavors of an object.   
Such a wrapper type should take into account the undefined aspects of  
doing such a thing.

> I think what you want for that is to somehow make SmartPtr!(X)  
> implicitly derived from SmartPtr!(const X), you don't want the compiler  
> applying blindly tail-const to all the members.

Again, it's logical const, no matter how you slice it.

-Steve


More information about the Digitalmars-d mailing list