Writing const-correct code in D
Kevin Bealer
Kevin_member at pathlink.com
Wed Mar 8 20:50:14 PST 2006
In article <Pine.LNX.4.64.0603081855530.30259 at bellevue.puremagic.com>, Brad
Roberts says...
>
>On Thu, 9 Mar 2006, Kevin Bealer wrote:
>
>> The same is true for struct, it gets copied in, which is fine for
>> small structs. For larger structs, you might want to pass by "in *",
>> i.e. use "in Foo *". You can modify this technique to use struct, for
>> that see the last item in the numbered list at the end.
>>
>>
>> For classes, the issue is that the pointer will not be modified with
>> the "in" convention, but the values in the class may be.
>>
>> : this(const_Foo b)
>> : {
>> : x1 = b.x1.dup;
>> : }
>
>I must have missed something somewhere along the way.. when did copying
>imply const? To me, something that's const can't be modified. That
>doesn't mean just to the caller, but also to the callee. It's a mechanism
>for saying "this object shouldn't be changed". Const by duplication
>doesn't help with the last part and make it entirely probable that code
>will at some point be change to modify parts of the passed in data with
>the expectation that those changes actually occur on up through to the
>caller.
>
>Sorry, const by dup is in some ways even worse than not having const. I
>see how it solves some usecases though, so it's not totally worse. :)
>
>Later,
>Brad
Yeah - this is a tradeoff, but as I understand it, the copy constructor in D
(unlike C++) can't be used for automatic conversions. So the person receiving a
const_Foo has to do this:
: void dofoo(in const_Foo x)
: {
: Foo y = new Foo(x); // explicit copy of value(s) from x
: ...
: }
..in order to get a new one. Now, normally one would not expect y to propagate
changes back to x, if the syntax looks like the above, right?
These versions won't even compile:
: void doAAA(in Foo x)
: {
: y.modifyStuff(); // okay here
: }
:
: void doBBB(in const_Foo x)
: {
: y.modifyStuff(); // failure here - const_Foo doesn't have this method
: }
:
: const_Foo bar;
:
: doAAA(bar); // error: can't convert const_Foo to Foo
: doBBB(bar); // okay here
So -- both are caught at *compile* time. No .duplication unless requested
explicitely. The clone() method and clone() constructors are designed to
do as deep of a copy as necessary, which means they need to be user defined.
That's why all the proposals for deep .dup don't work - it requires developer
input, the compiler doesn't know enough.
If you wanted to really prevent modification or copy, you can just omit that
method, and not provide a way to go from const_Foo to Foo. I'm proposing this
as the obvious standard way to de-const -- with a constructor -- for cases where
you want that behavior.
My thinking is that we could set up rules for people who want to do const, maybe
because they have a huge C++ project they are rewriting in D, and it uses const
in complex ways. Maybe because they just like the const facility.
Kevin
More information about the Digitalmars-d
mailing list