www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Yet another const system - for everyone to enjoy

reply Alex Burton <alexibu mac.com> writes:
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.
Sep 13 2007
next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 9/13/07, Alex Burton <alexibu mac.com> wrote:

The constructor of Bob is outrageously dodgy!
Bob() : changer(new Changer(this)), x(0) {}

You really shouldn't be passing "this" out of a constructor, when
"this" is not yet constructed!
Sep 13 2007
prev sibling parent reply James Dennett <jdennett acm.org> writes:
Alex Burton wrote:
 I wrote myself a piece of c++ code that proves how useless c++ const is.

I'll call it there. No piece of code you write can do any such thing; it can only show that const is useless in that piece of code, or at best show that const has some limitations. A compiler can't enforce logical constness perfectly without incorporating a full-blown language for correctness proofs, unless it has very unpleasant restrictions in its language. That doesn't make const or similar "useless". It just means you can't expect a silver bullet for ensuring correctness of code; it's still necessary to use human intelligence and good design as well as tools. -- James
Sep 13 2007
parent Alex Burton <alexibu mac.com> writes:
James Dennett Wrote:

 Alex Burton wrote:
 I wrote myself a piece of c++ code that proves how useless c++ const is.

I'll call it there. No piece of code you write can do any such thing; it can only show that const is useless in that piece of code, or at best show that const has some limitations. A compiler can't enforce logical constness perfectly without incorporating a full-blown language for correctness proofs, unless it has very unpleasant restrictions in its language. That doesn't make const or similar "useless". It just means you can't expect a silver bullet for ensuring correctness of code; it's still necessary to use human intelligence and good design as well as tools. -- James

Agreed. Useless it is not. That was an exaggeration, in the context of my previous arguments against transitive const.
Sep 13 2007