On Oct 28, 2012, at 10:09 PM, Peter Kasting <pkast...@chromium.org> wrote:

> On Sun, Oct 28, 2012 at 6:12 AM, Maciej Stachowiak <m...@apple.com> wrote:
> I am not sure a blanket rule is correct. If the Foo* is logically related to 
> the object with the foo() method and effectively would give access to mutable 
> internal state, then what you say is definitely correct. But if the const 
> object is a mere container that happens to hold pointers, there's no 
> particular reason it should turn them into const pointers. For example, it is 
> fine for const methods of HashSet or Vector to return non-const pointers if 
> that happens to be the template parameter type. In such cases, constness of 
> the container should only prevent you from mutating the container itself, not 
> from mutating anything held in the container, or else const containers of 
> non-const pointers (or non-const types in general) would be useless.
> 
> IMO const containers that vend non-const pointers _are_ nearly useless.
> 
> I consider logical constness to include not only "this statement has no 
> observable side effect" but also "this statement does not allow me to issue a 
> subsequent statement with observable side effects".  

Surely that's not quite correct as a definition of logical constness. You can 
always pass a const reference to another object's setter to cause an observable 
side effect. The scope of side effects under consideration has to be limited to 
the object itself plus anything else that could be considered part of its 
state. In brief, a const method on object O should neither mutate O nor expose 
the possibility of mutating the state of O, but it has no responsibility for 
its involvement in mutation of objets

> A const Vector that allows to to obtain a non-const element pointer, which 
> you subsequently mutate, means that you can mutate the vector.  (Consider for 
> example an element destructor that removes the element from the vector.)
> 
> If you allow const methods to return non-const pointers, it's almost always 
> possible to construct some chain of events that leads to mutation of the 
> const object or of state it can observe.  It is far easier to simply make 
> simple rules like "const methods shall not vend non-const pointers" than try 
> to allow it but guarantee that all the code everyone writes is safe.


Sure, there are unusual circumstances where calling non-const methods could 
cause totally unexpected side effects. But taking const strictness to this 
level makes it impossible to express some useful semantics.

Consider the following use case:

- I have collected a an ordered list of pointers to objects of type T in a 
Vector.
- I'd like to call a function that will operate on this list - it's allowed to 
do anything it wants to the Ts, including mutating them, but it can't alter the 
order or contents of the Vector.
(For example, I may want to pass the same list to another function).

Currently one would express this by passing a const Vector<T*>&. I don't see a 
good approach to this that strictly follows the suggested rule. You'd have to 
either copy the Vector to a temporary just for the call, or abandon 
const-correctness. Note that the other semantic (can't mutate the T's 
themselves) is currently available as const Vector<const T*>& but the proposal, 
strictly construed, would make those two types effectively identical.

I do think returning const pointers from accessors is generally the right thing 
when we aren't just talking about pure containers.

Regards,
Maciej


> 


_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-dev

Reply via email to