Yet another const system - for everyone to enjoy

Alex Burton alexibu at mac.com
Thu Sep 13 07:02:53 PDT 2007


I wrote myself a piece of c++ code that proves how useless c++ const is.
No use of mutable, no use of const_cast necessary.

Below the class Bob is easily changed by calling a const member function.

class Bob;

class Changer
{
	Bob * b;
public:	
	void change();

	Changer(Bob * b)
	: b(b) {}
};

class Bob
{
	Changer * changer;
	int x;
public:
	void changeInConst() const
	{
		changer->change();	
	}
	void change()
	{
		x++;
	}
	Bob()
		: changer(new Changer(this))
		, x(0)
       {}
	~Bob()
	{
		delete changer;
	}
};

void Changer::change()
{
	b->change();
}

int main (int argc, char * const argv[])
{
	Bob b;
	b.changeInConst();
	
    return 0;
}

Is this sort of thing why we need transitive const ?

I still think that transitive const will prove unworkable.

Maybe a good const system can't save us from code similar to the above but still catches a lot of simple errors.

Maybe there isn't a perfect const system that can work at compile time.

Two options : 

Run time const. Mutability checked at run time - but we don't like run time overheads.

Compiler gets an order of magnitude smarter and passes metadata around with function signatures about what calls what to make sure that the above case doesn't occur.
This doesn't sound too bad assuming its feasable.

Then we can have two types of const.

CONST #1
A properly enforced const where by const member functions are garanteed not to alter any agregate parts of the class. Either directly or indirectly.
They may however modify objects they have assocations with

e.g.
class Record
{
aggregate_parts:
	Fields[] fields;

associations:
	Socket socket;

	normal_const char[] readFirstFieldsName()
	{
		fields[0].name = "";						//doesn't compile - modifying aggregate part
		socket.send(QueryNameOfFirstField);			//does compile - modifying non aggregate part.
		return socket.receive();					//does compile
		return fields[0].name;						//this compiles
	}	
};

CONST #2
For thread safety checkable by compiler.
Full transitive const as described by Walter. Nothing can be changed from methods marked with a transitive_const keyword.

Most programs aren't multithreaded. In those that are (and have been designed well) most of the code is not called by multiple threads.

This means that CONST #2 will be rarely seen and only necessary for library writers and those doing multithreaded stuff.

Obviously nicer keywords could be chosen at a later date.



More information about the Digitalmars-d mailing list