Also, I do not think the claim that const member functions cannot have side effects is correct.
For example, it is OK, but very bad practice to have a const member function update a global integer counter.
class c { int m1; public: void set_m1( int i ) { m1 = i; } int calc( int i ) const { return m1 * 10; } };
calc is properly const, but it's not threadsafe.
On most systems, the value of calc will still be a race condition dependent on what thread gets there first, even if you lock around m1 or make it atomic. Calc will pull the value from m1 into a register, perform the operation, then return the newly calculated value. Another thread changing m1 will not matter.
Threadsafety(in this context) means that any sequence of calls of const-functions from any number of threads will have the same result. In your case there is a single const function, and you may call calc(0) from several threads and it always will return the same value. So it is pretty threadsafe.
Mutating m1 non-atomically is completely unrelated here, because non-const functions may be not threadsafe. You should just ensure that const functions are threadsafe.
This could be considered a non-thread safe operation.
Executing non-threadsafe function, and threadsafe function simultaneously is not a threadsafe operation. But the article says nothing about such situations, it places no restrictions on such situations. The thread-safe requirenment is for const-functions.
I am probably not a good explainer, so here is the link: http://stackoverflow.com/questions/14127379/does-const-mean-...
You could also argue that read/write locks aren't legitimate applications (starvation, increased contention, alternate solutions).
You're passing in a non-const reference, so wherever that came from would be expected to change. However the object itself would not change. Your object would be at StateA regardless of who gets the mutex first.
In this case the user of the library should be aware of which assumptions the library guarantees, not only what the current compiler does
* what the compiler will enforce: this has nothing to do with thread safety, and will allow what you mention.
* what guarantees the standard library will give:
[17.6.5.9/3] A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function’s non-const arguments, including this.
This means that the standard library assumes that your const objects will be thread safe in order to guarantee thread-safety itself. Updating a global without synchronization is not thread-safe.