Logical const

Peter Alexander peter.alexander.au at gmail.com
Sun Nov 28 06:50:53 PST 2010


On 28/11/10 11:25 AM, Jonathan M Davis wrote:
> So, _I_ am certainly not aware of a good solution, but if you play games, you
> should be able to get _something_ working. Overall though, I think that the
> lesson is that you should really be making const functions truly const and not
> try and deal with logical const at all.

Thanks for the reply Jonathan.

Your wording here worries me a little. You seem to be implying that 
logical const is some sort of arbitrary style choice, rather than a need 
that arises from real-life scenarios.

The only way you can write D-style const correct code is if you possess 
a crystal ball that will tell you whether you plan to cache accessors in 
the future. No real person can do that, so for all practical purposes, 
writing const correct code in D is impossible.

Again, the Matrix example: the *only* way to implement caching is to 
make getDeterminant() a non-const method. Great. That would be fine if 
the change was nice and localised, but what about other functions that 
use Matrix?

e.g.
Matrix getInverse(const Matrix m) { ... }

Getting the inverse of a matrix requires that you calculate its 
determinant, so this function won't work anymore because I can't call 
getDeterminant() with a const Matrix. The only choice I have now is to 
make getInverse take a non-const Matrix:

Matrix getInverse(Matrix m) { ... }

Solves the problem, but now I've created a new one: getInverse now has 
complete write access to my matrix, so when I do something as harmless as:

Matrix inv = getInverse(myMatrix);

This innocent call has now lost the guarantee that myMatrix will come 
out unmodified.

But wait, there's more:

class GameObject
{
    ...
    const Matrix getWorldTransform() const { return m_worldTransform; }
    Matrix m_worldTransform;
}

void renderGameObject(const GameObject obj) { ... }

What happens if renderGameObject needs to use getInverse, or getDeterminant?

1. I have to change getWorldTransform to be a non-const function that 
returns a non-const Matrix.

2. renderGameObject needs to be changed to receive a non-const GameObject.

3. I have lost any guarantee that rendering my GameObjects won't destroy 
them...

Surely I'm not the only person that finds something *incredibly* wrong 
with this!?


More information about the Digitalmars-d mailing list