[Interest] QMap and thread-safe.

Till Oliver Knoll till.oliver.knoll at gmail.com
Thu Jul 25 09:29:05 CEST 2013


I think the answer has already been given with regards to "mutable" and "const_cast", but at least I seem to have missed at least one reply (sent in private?) in this discussion. So here are my thoughts :)

Am 24.07.2013 um 09:29 schrieb Mandeep Sandhu <mandeepsandhu.chd at gmail.com>:

> ...
> Also, doesn't a "const" (old sense of the word) member function mean - "I'm not going to alter the state of the object" ?

I usually interpret a "const" as "I am not going to alter the state of the object - as far as YOU (the caller) are concerned, that is."

One canonical example has already been given with the "toLatin1" use case: "logically" the "state that is important to the caller - and accessible via the API!" must not (well, "should not") change when a "const" method is called.

However the class might do lazy initialisation and other optimisations like  allocating/updating *internal* cache structures. Those would then be declared "mutable".

So yes, requesting a "Latin1" representation of a given string does not alter the actual string, hence "logically" the state of the class does not change and declaring the toLatin1 method as const is the right thing to do.

> If so, that would make it thread-safe in the special scenario (mentioned by OP) where only "reads" are being attempted, right? Can an implementation make it thread-unsafe while still being const (again considering only the special "read-only" scenario)?

So by now we know that a "const" method can mess around with the "non-public internal state" as it pleases: allocate memory, write to mutable member variables etc. - so that makes it still thread-unsafe, even if your threads would only call the "const" (read) members!

Thiago has already given an example where a "const" method would allocate an internal (mutable) cache, and if that method would be called from different threads you might end up with leaked memory (in the best case - you might even end up with dangling pointers).

Microsoft is giving a "mutable" example with an access counter:

  http://msdn.microsoft.com/en-us/library/4h2h0ktk(v=vs.80).aspx

If that increment was not atomically implemented (and to be honest, right now I don't know whether a "foo++" is atomic - I don't think it is, is it?) and again two threads would call that method with the "wrong" timing, you might "miss" a count.

By the way IMHO that example is at least questionable: it is super simple to understand, but what would you do later on with such a counter? Block the caller after 1000 calls or return a different result then? Then in my opinion the "access counter" would be part of the "public logical state" of the class and hence any method changing that counter should /not/ be declared public!

If on the other hand you would "defragment some internal cache structures every 1000th call" then the "const" would probably be okay.


Bottom line: you walk on a very thin line when breaking the "const" with "mutable" (or "const_cast"). You can totally mis-use it and render the "const" completely meaningless, you can now rant about C++ letting you shoot into your foot (once again) and how "const" does not give you /any/ guarantee about thread-safety (as long as only "readers" are involved... (even though I understand that "reader-thread-safety"  is now the *intention* of the C++ 11 standard library...)


But think about it: having a loophole such as "mutable" is actually (ironically?) the only way(1) to make a class thread-safe while still offering const methods! (Java for instance does not even have the language concept of "const methods").

Because the other canonical example is declaring mutex variables as "mutable", because you still need/want to modify the state of a mutex, even in a const method :)

Cheers,
  Oliver

(1) Off course the language could also provide "special mutable mutex variables" and omit "mutable" etc. - but that would not be less awkward, and prevent the - rightful - use case of "internal cache modifications"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20130725/087a449d/attachment.html>


More information about the Interest mailing list