Transitive const sucks

Reiner Pope some at address.com
Wed Sep 12 04:47:46 PDT 2007


Walter Bright wrote:
> Janice Caron wrote:
>> So the function was declared const, because /conceptually/ it was.
>>
>> But the class had a mutable cache, declared with the C++ keyword 
>> "mutable"
>>
>> Transitivity would wreck that.
> 
> You're right in that transitive const does not support the notion of 
> "logical const" (which is the usual term for what you are referring to).
> 
> The problem with logical const, however, is it offers no semantic 
> guarantees. I pass a logical const reference around, and the underlying 
> data may or may not change. I have no guarantees one way or the other, 
> and even worse, I can't even tell this is happening. "I" here meaning 
> the compiler, and our hapless code auditor.
> 
> This just pulls the rug out from under:
> 
> 1) functional programming
> 2) multithreaded programming
> 3) having a tightly specified interface
> 
> It goes back to painting a stripe across your hips and calling it a 
> seatbelt.
> 
> Given this, it isn't any surprise that C++ is disastrously difficult to 
> write functional & multithreaded programs in, and C++ mutability is one 
> of the reasons why. In C++, you can write const this and const that and 
> it doesn't mean jack squat. Many experienced C++ programmers will tell 
> you that const is little more than a documentation aid.
> 
> In other words, you're quite right that transitive const totally wrecks 
> using const to specify logical constness. And that's a good thing <g>.

Is logical const really that bad? What would happen if you required in 
the spec that any changes made to a logical const variable must be 
undoable without changing the semantics of the program?

Suppose we have a logical const object with internal state, A. We then 
call a logical const method, getResult(), which caches the result 
internally, making the object's internal state B. As long as the caching 
is done correctly, then A.getResult() == B.getResult(), so the compiler 
is free to substitute B for A, or A for B whenever it wants.

As far as I can see, this re-enables the benefits of transitive const 
for functional and multi-threaded programming, as the compiler is free 
to ignore any changes to the variable, just as it is for transitive const.


   -- Reiner



More information about the Digitalmars-d mailing list