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