[webkit-dev] On returning mutable pointers from const methods
Peter Kasting
pkasting at chromium.org
Mon Oct 29 00:10:12 PDT 2012
On Sun, Oct 28, 2012 at 11:16 PM, Maciej Stachowiak <mjs at apple.com> wrote:
> On Oct 28, 2012, at 10:09 PM, Peter Kasting <pkasting at chromium.org> wrote:
>
> On Sun, Oct 28, 2012 at 6:12 AM, Maciej Stachowiak <mjs at 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
>
Sorry, I left out words. Consider the phrase "on the state of the object"
to be appended to both those quoted phrases I originally said.
I still think that it's extremely difficult to avoid "exposing the
possibility of mutating the state of O" in most cases. The mechanism may
be obscure, but it is frequently present -- frequently enough to make me
advocate for hard-and-fast rules.
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.
>
I think by "abandon const-correctness" you mean "pass a Vector<T*>*", which
is indeed the route I'd go. I don't consider that an abandonment of
const-correctness, in that you are indeed not violating logical constness.
But yes, you lose the ability to convey the idea that "this function, in
and of itself, doesn't modify the number or order of elements in the
vector". On the other hand, you don't put yourself in a position where a
caller of the function could then immediately use his returned T* to mutate
the vector -- which is often a real possibility in real-world systems.
There aren't any magic bullets here. Given that the compiler can very
rarely use "const" to optimize anything anyway, const is effectively
whatever we want it to be. I prefer hard guarantees that occur less
frequently to less-ironclad guarantees that are more common.
Reasonable people can disagree. I think your position -- that the hard
guarantee usually makes sense for non-simple-containers but you'd prefer to
allow a less-strict usage for simple containers -- is one that has some
appeal even if it's not what I'd personally choose (and is more complex to
explain/enforce). I certainly think we'd be in a better world if the
codebase followed this policy, compared to today.
PK
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20121029/ea599bf7/attachment.html>
More information about the webkit-dev
mailing list